///////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001-2009.
// -------------------------------------------------------------------------
//  File name:   LMG_ComputeWeight.cpp
//  Version:     v1.00
//  Created:     07/06/2009 by Jaewon Jung
//  Description: Locomotion Group utility functions
// -------------------------------------------------------------------------
//
///////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include <float.h>
#include "LMG.h"
#include "ModelAnimationSet.h"
#include <IRenderAuxGeom.h>
#include "CharacterInstance.h"
#include "Model.h"
#include "ModelSkeleton.h"
#include "CharacterManager.h"
#include "SDI.h"


namespace LMG
{
	namespace _private
	{

		void ComputeWeight4( Vec4 &Weight4, const Vec2& P, const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3 ) 
		{
			Vec4 w;	
			struct TW3
			{
				static ILINE void Weight3( const Vec2& p, const Vec2 &v0, const Vec2 &v1, const Vec2 &v2, f32&w0,f32&w1,f32&w2,f32&w3 )
				{
					w0=0;w1=0;w2=0;w3=0;
					Plane plane = Plane::CreatePlane( v0,v1,Vec3(v0.x,v0.y,1) ); 
					if ((plane|p)<=0)
					{
						Vec2 e0 = v0-v2;
						Vec2 e1 = v1-v2;
						Vec2 p2	=	p-v2;
						w0 =	p2.x*e1.y	- e1.x*p2.y;
						w1 =	e0.x*p2.y	-	p2.x*e0.y;
						w2 =	e0.x*e1.y -	e1.x*e0.y - w0-w1;
					}
				}
			};

			TW3::Weight3( P, p1,p3,p0,  w.y,w.w,w.x, w.z );
			Weight4=w;
			TW3::Weight3( P, p3,p1,p2,  w.w,w.y,w.z, w.x );
			Weight4+=w;
			TW3::Weight3( P, p2,p0,p1,  w.z,w.x,w.y, w.w );
			Weight4+=w;
			TW3::Weight3( P, p0,p2,p3,  w.x,w.z,w.w, w.y );
			Weight4+=w;

			Weight4 /= (Weight4.x+Weight4.y+Weight4.z+Weight4.w);

			if (Weight4.x<0)	Weight4.x=0;
			if (Weight4.y<0)	Weight4.y=0;
			if (Weight4.z<0)	Weight4.z=0;
			if (Weight4.w<0)	Weight4.w=0;
			if (Weight4.x>1)	Weight4.x=1;
			if (Weight4.y>1)	Weight4.y=1;
			if (Weight4.z>1)	Weight4.z=1;
			if (Weight4.w>1)	Weight4.w=1;
		}

		void ComputeWeightExtrapolate4( Vec4 &Weight4, const Vec2& P, const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3 ) 
		{
			Vec4 w;	
			struct TW3
			{
				static ILINE void Weight3( const Vec2& p, const Vec2 &v0, const Vec2 &v1, const Vec2 &v2, f32&w0,f32&w1,f32&w2,f32&w3 )
				{
					w0=0;w1=0;w2=0;w3=0;
					Plane plane = Plane::CreatePlane( v0,v1,Vec3(v0.x,v0.y,1) ); 
					if ((plane|p)<=0)
					{
						Vec2 e0 = v0-v2;
						Vec2 e1 = v1-v2;
						Vec2 p2	=	p-v2;
						w0 =	p2.x*e1.y	- e1.x*p2.y;
						w1 =	e0.x*p2.y	-	p2.x*e0.y;
						w2 =	e0.x*e1.y -	e1.x*e0.y - w0-w1;
					}
				}
			};

			TW3::Weight3( P, p1,p3,p0,  w.y,w.w,w.x, w.z );
			Weight4=w;
			TW3::Weight3( P, p3,p1,p2,  w.w,w.y,w.z, w.x );
			Weight4+=w;
			TW3::Weight3( P, p2,p0,p1,  w.z,w.x,w.y, w.w );
			Weight4+=w;
			TW3::Weight3( P, p0,p2,p3,  w.x,w.z,w.w, w.y );
			Weight4+=w;

			Weight4 /= (Weight4.x+Weight4.y+Weight4.z+Weight4.w);
		}

		LocomotionWeights6 ComputeWeightLoco6( Vec2& P,Vec2 &FL,Vec2 &FF,Vec2 &FR,  Vec2 &SL,Vec2 &SF,Vec2 &SR) 
		{
			LocomotionWeights6 w,Weight6(0,0,0, 0,0,0);

			if (P.x<0)
			{
				Vec4 w4;
				ComputeWeight4( w4, P, FL,SL,SF,FF ); 
				Weight6.fl+=w4.x;
				Weight6.sl+=w4.y;
				Weight6.sf+=w4.z;
				Weight6.ff+=w4.w;
			}
			else
			{
				Vec4 w4;
				ComputeWeight4( w4, P, FF,SF,SR,FR ); 
				Weight6.ff+=w4.x;
				Weight6.sf+=w4.y;
				Weight6.sr+=w4.z;
				Weight6.fr+=w4.w;
			}


			f32 sum = (Weight6.fl+Weight6.ff+Weight6.fr + Weight6.sl+Weight6.sf+Weight6.sr );
			if (sum)
			{
				Weight6 /= sum;
			}
			else
			{
				Weight6.fl=-1; Weight6.ff=-1; Weight6.fr=-1;
				Weight6.sl=-1; Weight6.sf=-1; Weight6.sr=-1;
			}

			return Weight6;
		}

		LocomotionWeights7 ComputeWeightLoco7( Vec2& P,Vec2 &FL,Vec2 &FF,Vec2 &FR,Vec2 &MF,Vec2 &SL,Vec2 &SF,Vec2 &SR) 
		{

			LocomotionWeights7 w,Weight7(0,0,0, 0, 0,0,0);
			struct TW3
			{
				static ILINE void Weight3a( Vec2 p,  Vec2 v0,Vec2 v1,Vec2 v2,   f32&w0,f32&w1,f32&w2,  f32&w3, f32&w4,f32&w5,f32&w6 )
				{
					w0=0; w1=0; w2=0; w3=0; w4=0; w5=0; w6=0;
					Plane plane = Plane::CreatePlane( v0,v1,Vec3(v0.x,v0.y,1) ); 
					if ((plane|p)<=0)
					{
						Vec2 e0 = v0-v2;
						Vec2 e1 = v1-v2;
						Vec2 p2	=	p-v2;
						w0 =	p2.x*e1.y	- e1.x*p2.y;
						w1 =	e0.x*p2.y	-	p2.x*e0.y;
						w2 =	e0.x*e1.y -	e1.x*e0.y - w0-w1;
					}
				}
				static ILINE void Weight3b( Vec2 p,  Vec2 v0,Vec2 v1,Vec2 v2,   f32&w0,f32&w1,f32&w2,  f32&w3, f32&w4,f32&w5,f32&w6 )
				{
					w0=0; w1=0; w2=0; w3=0; w4=0; w5=0; w6=0;
					Plane plane1 = Plane::CreatePlane( v0,v1,Vec3(v0.x,v0.y,1) ); 
					Plane plane2 = Plane::CreatePlane( v2,v0,Vec3(v2.x,v2.y,1) ); 
					if ((plane1|p)<=0 && (plane2|p)<=0)
					{
						Vec2 e0 = v0-v2;
						Vec2 e1 = v1-v2;
						Vec2 p2	=	p-v2;
						w0 =	p2.x*e1.y	- e1.x*p2.y;
						w1 =	e0.x*p2.y	-	p2.x*e0.y;
						w2 =	e0.x*e1.y -	e1.x*e0.y - w0-w1;
					}
				}
			};

			if (P.x<0)
			{
				TW3::Weight3a( P, MF,SL,SF,  w.mf,w.sl,w.sf, w.fl,w.ff,w.fr,w.sr );
				Weight7+=w;
				TW3::Weight3b( P, MF,FL,SL,  w.mf,w.fl,w.sl, w.ff,w.sf,w.fr,w.sr );
				Weight7+=w;
				TW3::Weight3a( P, FL,MF,FF,  w.fl,w.mf,w.ff, w.sl,w.sf,w.fr,w.sr );
				Weight7+=w;
			}
			else
			{
				TW3::Weight3a( P, SR,MF,SF,  w.sr,w.mf,w.sf, w.fr,w.ff,w.fl,w.sl );
				Weight7+=w;
				TW3::Weight3b( P, MF,SR,FR,  w.mf,w.sr,w.fr, w.ff,w.sf,w.fl,w.sl );
				Weight7+=w;
				TW3::Weight3a( P, MF,FR,FF,  w.mf,w.fr,w.ff, w.sr,w.sf,w.fl,w.sl );
				Weight7+=w;
			}

			f32 sum = (Weight7.fl+Weight7.ff+Weight7.fr + Weight7.mf + Weight7.sl+Weight7.sf+Weight7.sr );
			if (sum)
			{
				Weight7 /= sum;
			}
			else
			{
				assert(0);
				Weight7.fl=-1; Weight7.ff=-1; Weight7.fr=-1;
				Weight7.mf=-1;
				Weight7.sl=-1; Weight7.sf=-1; Weight7.sr=-1;
			}

			return Weight7;
		}

		struct BlendWeights_STF2
		{
			f32    ff; 
			f32 fl,   fr; 
			f32	   fb;

			f32    sf; 
			f32 sl,   sr; 
			f32	   sb;
		};

		StrafeWeights4 GetStrafingWeights4( Vec2 F, Vec2 L, Vec2 B, Vec2 R, Vec2 DesiredDirection );

		void ComputeWeight_STF2( const CAnimationSet* pAnimationSet, const SParametric& lmg, uint32 offset, BlendWeights_STF2& stf2, GlobalAnimationHeaderLMG& rGHLMG )
		{
			GlobalAnimationHeaderCAF* parrGlobalAnimations = &g_AnimationManager.m_arrGlobalCAF[0];

			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x00]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x01]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x02]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x03]) ]; 
			Vec3 vVelocity0=rGHLMG.m_arrBSAnimations[offset+0x00].m_qVelocity;
			Vec3 vVelocity1=rGHLMG.m_arrBSAnimations[offset+0x01].m_qVelocity;
			Vec3 vVelocity2=rGHLMG.m_arrBSAnimations[offset+0x02].m_qVelocity;
			Vec3 vVelocity3=rGHLMG.m_arrBSAnimations[offset+0x03].m_qVelocity;

			//	GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x04]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x05]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH06 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x06]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH07 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x07]) ]; 
			Vec3 vVelocity4=rGHLMG.m_arrBSAnimations[offset+0x04].m_qVelocity;
			Vec3 vVelocity5=rGHLMG.m_arrBSAnimations[offset+0x05].m_qVelocity;
			Vec3 vVelocity6=rGHLMG.m_arrBSAnimations[offset+0x06].m_qVelocity;
			Vec3 vVelocity7=rGHLMG.m_arrBSAnimations[offset+0x07].m_qVelocity;

			f32 x0	=	(lmg.m_BlendSpace.m_speed+1)*0.5f;
			f32 x1	=	1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;
			Vec2 bF = Vec2(vVelocity0*x0 + vVelocity4*x1);
			Vec2 bL = Vec2(vVelocity1*x0 + vVelocity5*x1);
			Vec2 bB = Vec2(vVelocity2*x0 + vVelocity6*x1);
			Vec2 bR = Vec2(vVelocity3*x0 + vVelocity7*x1);
			StrafeWeights4 blend = GetStrafingWeights4(bF, bL, bB, bR, lmg.m_BlendSpace.m_strafe);

			f32 t = lmg.m_BlendSpace.m_strafe.GetLength();
			blend.f	=	blend.f*t + 0.25f*(1.0f-t);
			blend.l	=	blend.l*t + 0.25f*(1.0f-t);	
			blend.b	=	blend.b*t + 0.25f*(1.0f-t);
			blend.r	=	blend.r*t + 0.25f*(1.0f-t);	

			stf2.ff=blend.f*x0;	
			stf2.fl=blend.l*x0;	
			stf2.fb=blend.b*x0;
			stf2.fr=blend.r*x0;	

			stf2.sf=blend.f*x1;	
			stf2.sl=blend.l*x1;	
			stf2.sb=blend.b*x1;
			stf2.sr=blend.r*x1;	

			return;
		}

		struct BlendWeights_S2
		{
			f32      ff; 
			f32   ffl; 
			f32 fl,       fr; 
			f32	      fbr;
			f32	     fb;

			f32      sf; 
			f32   sfl; 
			f32 sl,       sr; 
			f32	      sbr;
			f32	     sb;
		};

		StrafeWeights6 GetStrafingWeights6( Vec2 F,Vec2 FL,Vec2 L,  Vec2 B,Vec2 BR,Vec2 R, const Vec2& DesiredDirection   );
		StrafeWeights8 GetStrafingWeights8( Vec2 F,Vec2 FL,Vec2 L,Vec2 LB,   Vec2 B,Vec2 BR,Vec2 R,Vec2 RF,   const Vec2& DesiredDirection );

		SPU_NO_INLINE void ComputeWeight_S2( const CAnimationSet* pAnimationSet, const SParametric& lmg, uint32 offset, BlendWeights_S2& s2, GlobalAnimationHeaderLMG& rGHLMG )
		{
			GlobalAnimationHeaderCAF* parrGlobalAnimations = &g_AnimationManager.m_arrGlobalCAF[0];

			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x00]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x01]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x02]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x03]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x04]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x05]) ]; 
			Vec3 vVelocity00=rGHLMG.m_arrBSAnimations[offset+0x00].m_qVelocity;
			Vec3 vVelocity01=rGHLMG.m_arrBSAnimations[offset+0x01].m_qVelocity;
			Vec3 vVelocity02=rGHLMG.m_arrBSAnimations[offset+0x02].m_qVelocity;
			Vec3 vVelocity03=rGHLMG.m_arrBSAnimations[offset+0x03].m_qVelocity;
			Vec3 vVelocity04=rGHLMG.m_arrBSAnimations[offset+0x04].m_qVelocity;
			Vec3 vVelocity05=rGHLMG.m_arrBSAnimations[offset+0x05].m_qVelocity;

			//	GlobalAnimationHeaderCAF& rsubGAH06 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x06]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH07 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x07]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH08 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x08]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH09 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x09]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH0a = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x0a]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH0b = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x0b]) ]; 
			Vec3 vVelocity06=rGHLMG.m_arrBSAnimations[offset+0x06].m_qVelocity;
			Vec3 vVelocity07=rGHLMG.m_arrBSAnimations[offset+0x07].m_qVelocity;
			Vec3 vVelocity08=rGHLMG.m_arrBSAnimations[offset+0x08].m_qVelocity;
			Vec3 vVelocity09=rGHLMG.m_arrBSAnimations[offset+0x09].m_qVelocity;
			Vec3 vVelocity0a=rGHLMG.m_arrBSAnimations[offset+0x0a].m_qVelocity;
			Vec3 vVelocity0b=rGHLMG.m_arrBSAnimations[offset+0x0b].m_qVelocity;

			f32 x0=(lmg.m_BlendSpace.m_speed+1)*0.5f;
			f32 x1=1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;

			Vec2 sF		= Vec2(vVelocity00*x0 + vVelocity06*x1);
			Vec2 sFL	= Vec2(vVelocity01*x0 + vVelocity07*x1);
			Vec2 sL		= Vec2(vVelocity02*x0 + vVelocity08*x1);
			Vec2 sB		= Vec2(vVelocity03*x0 + vVelocity09*x1);
			Vec2 sBR	= Vec2(vVelocity04*x0 + vVelocity0a*x1);
			Vec2 sR		= Vec2(vVelocity05*x0 + vVelocity0b*x1);
			StrafeWeights6 blend = GetStrafingWeights6(sF,sFL,sL, sB,sBR,sR, lmg.m_BlendSpace.m_strafe );

			f32 t = lmg.m_BlendSpace.m_strafe.GetLength();
			f32 p =	(1.0f/6.0f);
			blend.f		=	blend.f*t		+ p*(1.0f-t);
			blend.fl	=	blend.fl*t	+ p*(1.0f-t);
			blend.l		=	blend.l*t		+ p*(1.0f-t);	
			blend.b		=	blend.b*t		+ p*(1.0f-t);
			blend.br	=	blend.br*t	+ p*(1.0f-t);
			blend.r		=	blend.r*t		+ p*(1.0f-t);	

			s2.ff		=x0*blend.f;	
			s2.ffl	=x0*blend.fl;	
			s2.fl		=x0*blend.l;	
			s2.fb		=x0*blend.b;	
			s2.fbr	=x0*blend.br;	
			s2.fr		=x0*blend.r;	

			s2.sf		=x1*blend.f;	
			s2.sfl	=x1*blend.fl;	
			s2.sl		=x1*blend.l;	
			s2.sb		=x1*blend.b;	
			s2.sbr	=x1*blend.br;	
			s2.sr		=x1*blend.r;	

			return;
		}

		struct BlendWeights_ST2
		{
			f32      ff; 
			f32   ffl; 
			f32 fl,       fr; 
			f32	      fbr;
			f32	     fb;

			f32      mf; 

			f32      sf; 
			f32   sfl; 
			f32 sl,       sr; 
			f32	      sbr;
			f32	     sb;

			f32	fftl,fftr; 
			f32	sftl,sftr; 
		};

		SPU_NO_INLINE void ComputeWeight_ST2( const CAnimationSet* pAnimationSet, const SParametric& lmg, uint32 offset, BlendWeights_ST2& st2, GlobalAnimationHeaderLMG& rGHLMG )
		{
			GlobalAnimationHeaderCAF* parrGlobalAnimations = &g_AnimationManager.m_arrGlobalCAF[0];

			GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x00]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x01]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x02]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x03]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x04]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x05]) ]; 
			Vec3 vVelocity00=rGHLMG.m_arrBSAnimations[offset+0x00].m_qVelocity;
			Vec3 vVelocity01=rGHLMG.m_arrBSAnimations[offset+0x01].m_qVelocity;
			Vec3 vVelocity02=rGHLMG.m_arrBSAnimations[offset+0x02].m_qVelocity;
			Vec3 vVelocity03=rGHLMG.m_arrBSAnimations[offset+0x03].m_qVelocity;
			Vec3 vVelocity04=rGHLMG.m_arrBSAnimations[offset+0x04].m_qVelocity;
			Vec3 vVelocity05=rGHLMG.m_arrBSAnimations[offset+0x05].m_qVelocity;

			GlobalAnimationHeaderCAF& rsubGAH06 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x06]) ]; 
			Vec3 vVelocity06=rGHLMG.m_arrBSAnimations[offset+0x06].m_qVelocity;

			GlobalAnimationHeaderCAF& rsubGAH07 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x07]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH08 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x08]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH09 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x09]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH0a = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x0a]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH0b = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x0b]) ]; 
			//		GlobalAnimationHeaderCAF& rsubGAH0c = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x0c]) ]; 
			Vec3 vVelocity07=rGHLMG.m_arrBSAnimations[offset+0x07].m_qVelocity;
			Vec3 vVelocity08=rGHLMG.m_arrBSAnimations[offset+0x08].m_qVelocity;
			Vec3 vVelocity09=rGHLMG.m_arrBSAnimations[offset+0x09].m_qVelocity;
			Vec3 vVelocity0a=rGHLMG.m_arrBSAnimations[offset+0x0a].m_qVelocity;
			Vec3 vVelocity0b=rGHLMG.m_arrBSAnimations[offset+0x0b].m_qVelocity;
			Vec3 vVelocity0c=rGHLMG.m_arrBSAnimations[offset+0x0c].m_qVelocity;

			//calculate the strafe-weights
			f32	speed = lmg.m_BlendSpace.m_speed;
			f32 fmid=1-fabsf(speed);
			//	f32 ffast=0;
			//	if (speed>0) ffast=speed; else fslow=1-(speed+1);
			f32 x0	=	(lmg.m_BlendSpace.m_speed+1)*0.5f; // fast
			f32 x1	= 1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;	//slow

			Vec2 sF		= Vec2(vVelocity00*x0 + vVelocity07*x1);
			Vec2 sFL	= Vec2(vVelocity01*x0 + vVelocity08*x1);
			Vec2 sL		= Vec2(vVelocity02*x0 + vVelocity09*x1);
			Vec2 sB		= Vec2(vVelocity03*x0 + vVelocity0a*x1);
			Vec2 sBR	= Vec2(vVelocity04*x0 + vVelocity0b*x1);
			Vec2 sR		= Vec2(vVelocity05*x0 + vVelocity0c*x1);
			StrafeWeights6 blend = GetStrafingWeights6(sF,sFL,sL, sB,sBR,sR, lmg.m_BlendSpace.m_strafe );
			f32 ts		= lmg.m_BlendSpace.m_strafe.GetLength();
			f32 ps		=	(1.0f/6.0f);
			blend.f		=	blend.f*ts		+ ps*(1.0f-ts);
			blend.fl	=	blend.fl*ts	  + ps*(1.0f-ts);
			blend.l		=	blend.l*ts		+ ps*(1.0f-ts);	
			blend.b		=	blend.b*ts		+ ps*(1.0f-ts);
			blend.br	=	blend.br*ts	  + ps*(1.0f-ts);
			blend.r		=	blend.r*ts		+ ps*(1.0f-ts);	
			StrafeWeights6 StrafeWeights=blend;

			//	f32 L_fast=rsubGAH0d.m_fMoveSpeed;	f32 R_fast=rsubGAH0e.m_fMoveSpeed;
			f32 F_fast=rsubGAH00.m_fMoveSpeed;	
			f32 F_mid	=rsubGAH06.m_fMoveSpeed;
			//	f32 L_slow=rsubGAH0f.m_fMoveSpeed;	f32 R_slow=rsubGAH10.m_fMoveSpeed;
			f32 F_slow=rsubGAH07.m_fMoveSpeed;	

			//	f32 TL_fast=rsubGAH0d.m_fTurnSpeed;		f32 TF_fast=rsubGAH00.m_fTurnSpeed;	f32 TR_fast=rsubGAH0e.m_fTurnSpeed;
			//	f32 TF_mid =rsubGAH06.m_fTurnSpeed;
			//	f32 TL_slow=rsubGAH0f.m_fTurnSpeed;	f32 TF_slow=rsubGAH07.m_fTurnSpeed;	f32 TR_slow=rsubGAH10.m_fTurnSpeed;


			f32 f0 = F_mid	-F_slow;
			f32 f1 = F_fast -F_slow;
			f32 mid=f0;
			if (f1)
				mid = (f0/f1)*2-1;

			//calculate the turn-weights
			Vec2 FL=Vec2(-1, 1);	//fast left	
			Vec2 FF=Vec2( 0, 1);	//fast speed forward	
			Vec2 FR=Vec2( 1, 1);	//fast right	

			Vec2 MF=Vec2( 0, mid);	//middle speed forward	

			Vec2 SL=Vec2(-1,-1);	//slow left
			Vec2 SF=Vec2( 0,-1);	//slow speed forward	
			Vec2 SR=Vec2( 1,-1);	//slow right
			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);
			LocomotionWeights7 TurnWeights = ComputeWeightLoco7( p, FL,FF,FR, MF, SL,SF,SR );

			Vec2 strafe = lmg.m_BlendSpace.m_strafe.GetNormalizedSafe( Vec2(0,0) );

			f32 fTurnPriority=0;

			if (pAnimationSet->m_CharEditMode)
			{
				f32 rad = atan2f(strafe.x,strafe.y);
				fTurnPriority = fabsf( rad*2 ); //*turnweight;
				if (fTurnPriority>1.0f) fTurnPriority=1.0f;
				fTurnPriority=1.0f-fTurnPriority;
			}
			else
			{
				fTurnPriority = lmg.m_params[eMotionParamID_Curving].value;
			}

			fTurnPriority*=ts;		// disables turning when standing still

			//new:
			fTurnPriority*=clamp_tpl(strafe.y, 0.0f, 1.0f);  // blend in turn assets depending on amount of forward motion
			fTurnPriority*=fabsf(p.x); // blend out turn assets when not turning fully

			//old:   fTurnPriority*=clamp( (lmg.m_BlendSpace.m_fAllowLeaningSmooth*1.4f)-0.2f, 0.0f,1.0f);

			f32 staf = 1.0f-fTurnPriority;
			f32 turn = fTurnPriority;

			st2.ff	=	staf*x0*StrafeWeights.f+turn*TurnWeights.ff;	//fast forward speed
			st2.ffl	=	staf*x0*StrafeWeights.fl;	
			st2.fl	=	staf*x0*StrafeWeights.l;	
			st2.fb	=	staf*x0*StrafeWeights.b;	
			st2.fbr	=	staf*x0*StrafeWeights.br;	
			st2.fr	=	staf*x0*StrafeWeights.r;	

			st2.mf	=	turn*TurnWeights.mf;	//middle forward speed	

			st2.sf	=	staf*x1*StrafeWeights.f+turn*TurnWeights.sf;	//slow forward speed
			st2.sfl	=	staf*x1*StrafeWeights.fl;	
			st2.sl	=	staf*x1*StrafeWeights.l;	
			st2.sb	=	staf*x1*StrafeWeights.b;	
			st2.sbr	=	staf*x1*StrafeWeights.br;	
			st2.sr	=	staf*x1*StrafeWeights.r;	

			st2.fftl=turn*TurnWeights.fl;	//left
			st2.fftr=turn*TurnWeights.fr;	//right
			st2.sftl=turn*TurnWeights.sl;	//left
			st2.sftr=turn*TurnWeights.sr;	//right

			assert( fabsf((st2.ff+st2.ffl+st2.fl+st2.fb+st2.fbr+st2.fr + st2.mf + st2.sf+st2.sfl+st2.sl+st2.sb+st2.sbr+st2.sr +(st2.fftl+st2.fftr+st2.sftl+st2.sftr))-1.0f)<0.03f );
		}

		struct BlendWeights_STX
		{
			f32      ff; 
			f32 fl,       fr; 
			f32	     fb;

			f32      mf; 

			f32      sf; 
			f32 sl,       sr; 
			f32	     sb;

			f32	fftl,fftr; //9-a
			f32	sftl,sftr; //b-c
		};

		void ComputeWeight_STX( const CAnimationSet* pAnimationSet, const SParametric& lmg, uint32 offset, BlendWeights_STX& stx, GlobalAnimationHeaderLMG& rGHLMG )
		{
			GlobalAnimationHeaderCAF* parrGlobalAnimations = &g_AnimationManager.m_arrGlobalCAF[0];

			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x00]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x01]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x02]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x03]) ]; 
			Vec3 vVelocity00=rGHLMG.m_arrBSAnimations[offset+0x00].m_qVelocity;
			Vec3 vVelocity01=rGHLMG.m_arrBSAnimations[offset+0x01].m_qVelocity;
			Vec3 vVelocity02=rGHLMG.m_arrBSAnimations[offset+0x02].m_qVelocity;
			Vec3 vVelocity03=rGHLMG.m_arrBSAnimations[offset+0x03].m_qVelocity;

			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x05]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH06 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x06]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH07 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x07]) ]; 
			//	GlobalAnimationHeaderCAF& rsubGAH08 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[offset+0x08]) ]; 
			Vec3 vVelocity05=rGHLMG.m_arrBSAnimations[offset+0x05].m_qVelocity;
			Vec3 vVelocity06=rGHLMG.m_arrBSAnimations[offset+0x06].m_qVelocity;
			Vec3 vVelocity07=rGHLMG.m_arrBSAnimations[offset+0x07].m_qVelocity;
			Vec3 vVelocity08=rGHLMG.m_arrBSAnimations[offset+0x08].m_qVelocity;

			//calculate the strafe-weights
			f32	t = lmg.m_BlendSpace.m_speed;
			f32 ffast=0,fmid=1-fabsf(t),fslow=0;
			if (t>0) ffast=t; else fslow=1-(t+1);
			f32 x0	=	(lmg.m_BlendSpace.m_speed+1)*0.5f; // fast
			f32 x1 = 1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;	//slow

			Vec2 sF		= Vec2(vVelocity00*x0 + vVelocity00*x1);
			Vec2 sL		= Vec2(vVelocity01*x0 + vVelocity06*x1);
			Vec2 sB		= Vec2(vVelocity02*x0 + vVelocity07*x1);
			Vec2 sR		= Vec2(vVelocity03*x0 + vVelocity08*x1);
			StrafeWeights4 blend = GetStrafingWeights4(sF,sL,sB,sR, lmg.m_BlendSpace.m_strafe );

			Vec2 dirF	=	Vec2( 0,+1); //0
			Vec2 dirL	=	Vec2(-1, 0); //2
			Vec2 dirB	=	Vec2( 0,-1); //3
			Vec2 dirR	=	Vec2(+1, 0); //5
			Vec2 movedir= dirF*blend.f +  dirL*blend.l + dirB*blend.b + dirR*blend.r;
			f32 length = lmg.m_BlendSpace.m_strafe.GetLength();
			f32 lmd = movedir.GetLength();
			if (lmd>length)	{	movedir.NormalizeSafe(Vec2(0,1)); movedir*=length;	}
			Vec4 StrafeWeights;
			ComputeWeight4(StrafeWeights,movedir, dirF,dirL,dirB,dirR);

			//calculate the turn-weights
			Vec2 FL=Vec2(-1, 1);	//fast left	
			Vec2 FF=Vec2( 0, 1);	//fast speed forward	
			Vec2 FR=Vec2( 1, 1);	//fast right	

			Vec2 MF=Vec2( 0, 0);	//middle speed forward	

			Vec2 SL=Vec2(-1,-1);	//slow left
			Vec2 SF=Vec2( 0,-1);	//slow speed forward	
			Vec2 SR=Vec2( 1,-1);	//slow right
			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);
			LocomotionWeights7 TurnWeights = ComputeWeightLoco7( p, FL,FF,FR, MF, SL,SF,SR );

			Vec2 strafe = lmg.m_BlendSpace.m_strafe.GetNormalizedSafe( Vec2(0,0) );

			f32 turnweight = fabsf(lmg.m_BlendSpace.m_turn);

			f32 rad = atan2f(strafe.x,strafe.y);
			f32 fTurnPriority = fabsf( rad*2 ); //*turnweight;
			if (fTurnPriority>1.0f) fTurnPriority=1.0f;

			fTurnPriority = lmg.m_params[eMotionParamID_Curving].value;

			f32 staf = fTurnPriority;
			f32 turn = 1.0f-fTurnPriority;

			f32 tw = turnweight*4;
			if (tw>1.0f)
				tw=1.0f;

			//turn*=tw; 
			staf=1.0f-turn; 

			stx.ff	=	staf*ffast*StrafeWeights.x+turn*TurnWeights.ff;	//fast forward speed
			stx.fl	=	staf*x0*   StrafeWeights.y;	
			stx.fb	=	staf*x0*   StrafeWeights.z;	
			stx.fr	=	staf*x0*   StrafeWeights.w;	

			stx.mf	=	staf*fmid* StrafeWeights.x+turn*TurnWeights.mf;		//middle forward speed	

			stx.sf	=	staf*fslow*StrafeWeights.x+turn*TurnWeights.sf;	//slow forward speed
			stx.sl	=	staf*x1*   StrafeWeights.y;	
			stx.sb	=	staf*x1*   StrafeWeights.z;	
			stx.sr	=	staf*x1*   StrafeWeights.w;	

			stx.fftl=turn*TurnWeights.fl;	//left
			stx.fftr=turn*TurnWeights.fr;	//right
			stx.sftl=turn*TurnWeights.sl;	//left
			stx.sftr=turn*TurnWeights.sr;	//right
		}

		// [artem]: refactor this !!!
		float GetParamScale(const SParametric & lmg)
		{
			const MotionParam & param = lmg.m_params[eMotionParamID_Scale];
			return param.desc.m_fMin + param.blendspace.m_fAssetBlend * (param.desc.m_fMax - param.desc.m_fMin);
		}

		void ComputeWeight_IROT(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	t = lmg.m_BlendSpace.m_turn;
			if (t<0)
			{
				lmg.m_fBlendWeight[1]=1+t;	//middle
				lmg.m_fBlendWeight[2]=-t;		//left
			}
			else
			{
				lmg.m_fBlendWeight[0]=t;		//right
				lmg.m_fBlendWeight[1]=1-t;	//middle
			}			

			//	float fColDebug[4] = {1,1,0,1};
			//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"IROT: %f %f %f      t: %f", lmg.m_fBlendWeight[0],lmg.m_fBlendWeight[1],lmg.m_fBlendWeight[2],t );	
			//	g_YLine+=16.0f;


		}

		void ComputeWeight_TSTP(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	t = lmg.m_BlendSpace.m_turn;
			t = CLAMP(t, -1.0f, 1.0f);
			if (t<0)
			{
				lmg.m_fBlendWeight[1]=1+t;	//middle
				lmg.m_fBlendWeight[2]=-t;		//left
			}
			else
			{
				lmg.m_fBlendWeight[0]=t;    //right
				lmg.m_fBlendWeight[1]=1-t;  //middle
			}			

			//		float fColDebug[4] = {1,1,0,1};
			//		g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"TSTP: %f %f %f      t: %f", lmg.m_fBlendWeight[0],lmg.m_fBlendWeight[1],lmg.m_fBlendWeight[2], t );	
			//		g_YLine+=16.0f;

#ifdef _DEBUG
			f32 fTotal=0.0f;
			for (uint32 i=0; i<3; i++)
				fTotal+=lmg.m_fBlendWeight[i];
			assert( fabsf(fTotal-1.0f)<0.005f );

			uint32 nExtrapolation1=0;
			for (uint32 i=0; i<3; i++)
				nExtrapolation1 |= uint32(lmg.m_fBlendWeight[i]<-0.2f);
			assert(nExtrapolation1==0);

			uint32 nExtrapolation2=0;
			for (uint32 i=0; i<3; i++)
				nExtrapolation2 |= uint32(lmg.m_fBlendWeight[i]>1.2f);
			assert(nExtrapolation2==0);
#endif

		}

		void ComputeWeight_M2I1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			lmg.m_fBlendWeight[0]=1.0f;
		}
		void ComputeWeight_STOP(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			uint32 idx = lmg.m_nStopIndex;
			lmg.m_fBlendWeight[idx]=1.0f;

		//	float fColDebug[4] = {1,1,0,1};
		//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"m_nStopIndex: %d", idx );	
		//	g_YLine+=16.0f;
		}

		IdleStepWeights6 GetIdle2MoveWeights6(  Vec2 DesiredDirection  );
		void ComputeWeight_I2M1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			Vec2 mdir = lmg.m_BlendSpace.m_strafe.GetNormalizedSafe(Vec2(0,1)); // fowrard by default (this used to be right)
			IdleStepWeights6 I2M = GetIdle2MoveWeights6(mdir); 	
			lmg.m_fBlendWeight[0]=I2M.fr;
			lmg.m_fBlendWeight[1]=I2M.rr;
			lmg.m_fBlendWeight[2]=I2M.br;
			lmg.m_fBlendWeight[3]=I2M.fl;
			lmg.m_fBlendWeight[4]=I2M.ll;
			lmg.m_fBlendWeight[5]=I2M.bl;	
		}

		void ComputeWeight_I2MT(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			Vec2 mdir = lmg.m_BlendSpace.m_strafe.GetNormalizedSafe(Vec2(0,1)); //forward by default
			IdleStepWeights6 I2M = GetIdle2MoveWeights6(mdir); 	
			f32 t0 = fabsf(lmg.m_BlendSpace.m_turn) <= 0.2f; // use strafe assets when not turning (rather arbitrary value)
			f32 t1 = 1.0f - t0;

			lmg.m_fBlendWeight[ 0]=I2M.fr*t0;
			lmg.m_fBlendWeight[ 1]=I2M.rr*t0;
			lmg.m_fBlendWeight[ 2]=I2M.br*t0;
			lmg.m_fBlendWeight[ 3]=I2M.fl*t0;
			lmg.m_fBlendWeight[ 4]=I2M.ll*t0;
			lmg.m_fBlendWeight[ 5]=I2M.bl*t0;

			lmg.m_fBlendWeight[ 6]=I2M.fr*t1;
			lmg.m_fBlendWeight[ 7]=I2M.rr*t1;
			lmg.m_fBlendWeight[ 8]=I2M.br*t1;
			lmg.m_fBlendWeight[ 9]=I2M.fl*t1;
			lmg.m_fBlendWeight[10]=I2M.ll*t1;
			lmg.m_fBlendWeight[11]=I2M.bl*t1;
		}

		void ComputeWeight_I2M2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			Vec2 mdir = lmg.m_BlendSpace.m_strafe.GetNormalizedSafe(Vec2(0,1)); //forward-right
			IdleStepWeights6 I2M = GetIdle2MoveWeights6(mdir); 

			f32 t0=1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;
			f32 t1=(lmg.m_BlendSpace.m_speed+1)*0.5f;

			// Force fastest speed
			//		t1=1; t0=0;

			lmg.m_fBlendWeight[ 0]=I2M.fr*t0;
			lmg.m_fBlendWeight[ 1]=I2M.rr*t0;
			lmg.m_fBlendWeight[ 2]=I2M.br*t0;
			lmg.m_fBlendWeight[ 3]=I2M.fl*t0;
			lmg.m_fBlendWeight[ 4]=I2M.ll*t0;
			lmg.m_fBlendWeight[ 5]=I2M.bl*t0;

			lmg.m_fBlendWeight[ 6]=I2M.fr*t1;
			lmg.m_fBlendWeight[ 7]=I2M.rr*t1;
			lmg.m_fBlendWeight[ 8]=I2M.br*t1;
			lmg.m_fBlendWeight[ 9]=I2M.fl*t1;
			lmg.m_fBlendWeight[10]=I2M.ll*t1;
			lmg.m_fBlendWeight[11]=I2M.bl*t1;

			/*
			float fColDebug[4] = {1,1,0,1};

			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"m_speed: %f" , lmg.m_BlendSpace.m_speed );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow0: %f  fast0: %f",lmg.m_fBlendWeight[ 0],lmg.m_fBlendWeight[ 6] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow1: %f  fast1: %f",lmg.m_fBlendWeight[ 1],lmg.m_fBlendWeight[ 7] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow2: %f  fast2: %f",lmg.m_fBlendWeight[ 2],lmg.m_fBlendWeight[ 8] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow3: %f  fast3: %f",lmg.m_fBlendWeight[ 3],lmg.m_fBlendWeight[ 9] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow4: %f  fast4: %f",lmg.m_fBlendWeight[ 4],lmg.m_fBlendWeight[10] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow5: %f  fast5: %f",lmg.m_fBlendWeight[ 5],lmg.m_fBlendWeight[11] );	
			g_YLine+=16.0f;
			*/
		}

		void ComputeWeight_XIM2(SParametric & lmg, const CAnimationSet* pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rLMG)
		{
			if (rLMG.m_nInitialized==0)
			{
				uint32 init_count=0;
				uint32 numAssets = rLMG.m_arrBSAnimations.size();
				for (uint32 i=0; i<numAssets; i++)
				{
					int32 animID = pAnimationSet->GetAnimIDByCRC(rLMG.m_arrBSAnimations[i].m_animName.m_CRC32);
					assert(animID>=0);
					int32 globalID = pAnimationSet->GetGlobalIDByAnimID_Fast(animID);
					assert(globalID>=0);
					if (globalID < 0)
						break;

					GlobalAnimationHeaderCAF& rCAF = g_AnimationManager.m_arrGlobalCAF[globalID];
					const CModelJoint* pRootJoint	= &pAnimationSet->m_pModel->m_ModelSkeleton.m_arrModelJoints[0];
					IController* pController = rCAF.GetControllerByJointCRC32(pRootJoint->m_nJointCRC32);
					if (pController==0)
						continue;

					f32 duration = rCAF.m_fEndSec-rCAF.m_fStartSec;
					uint32 numKeys = uint32( (duration/SECONDS_PER_TICK) +1);
					f32 timestep = 1.0f/f32(numKeys);
					f32 t=0.0f;
					std::vector<Vec3> root_keys;
					root_keys.resize(numKeys);	

					for (uint32 k=0; k<numKeys; k++)
					{
						pController->GetP( rCAF.NTime2KTime(t), root_keys[k]);
						t += timestep;
					}

					f32 speed = 0.0f; 
					uint32 poses=5;
					for (uint32 k=(numKeys-poses-1); k<(numKeys-1); k++)
						speed += (root_keys[k+0]-root_keys[k+1]).GetLength()*30.0f; 

					speed/=poses;

					rCAF.m_fMoveSpeed =	speed;
					rLMG.m_arrBSAnimations[i].m_qVelocity=Vec3(0,speed,0);
					init_count++;
				}

				if (init_count==numAssets)
					rLMG.m_nInitialized=true;
			}

			f32 rad = lmg.m_BlendSpace.m_turn*gf_PI;
			Vec2 mdir = Vec2(cry_sinf(rad),cry_cosf(rad));
			IdleStepWeights6 I2M = GetIdle2MoveWeights6(mdir); 

			f32 t0=1.0f-(lmg.m_BlendSpace.m_speed+1)*0.5f;
			f32 t1=(lmg.m_BlendSpace.m_speed+1)*0.5f;

			lmg.m_fBlendWeight[ 0]=I2M.fr*t0;
			lmg.m_fBlendWeight[ 1]=I2M.rr*t0;
			lmg.m_fBlendWeight[ 2]=I2M.br*t0;
			lmg.m_fBlendWeight[ 3]=I2M.fl*t0;
			lmg.m_fBlendWeight[ 4]=I2M.ll*t0;
			lmg.m_fBlendWeight[ 5]=I2M.bl*t0;

			lmg.m_fBlendWeight[ 6]=I2M.fr*t1;
			lmg.m_fBlendWeight[ 7]=I2M.rr*t1;
			lmg.m_fBlendWeight[ 8]=I2M.br*t1;
			lmg.m_fBlendWeight[ 9]=I2M.fl*t1;
			lmg.m_fBlendWeight[10]=I2M.ll*t1;
			lmg.m_fBlendWeight[11]=I2M.bl*t1;

			/*
			float fColDebug[4] = {1,1,0,1};

			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"m_speed: %f" , lmg.m_BlendSpace.m_speed );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow0: %f  fast0: %f",lmg.m_fBlendWeight[ 0],lmg.m_fBlendWeight[ 6] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow1: %f  fast1: %f",lmg.m_fBlendWeight[ 1],lmg.m_fBlendWeight[ 7] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow2: %f  fast2: %f",lmg.m_fBlendWeight[ 2],lmg.m_fBlendWeight[ 8] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow3: %f  fast3: %f",lmg.m_fBlendWeight[ 3],lmg.m_fBlendWeight[ 9] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow4: %f  fast4: %f",lmg.m_fBlendWeight[ 4],lmg.m_fBlendWeight[10] );	
			g_YLine+=16.0f;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"slow5: %f  fast5: %f",lmg.m_fBlendWeight[ 5],lmg.m_fBlendWeight[11] );	
			g_YLine+=16.0f;
			*/

		}

		IdleStepWeights6 GetIdleStepWeights6(   Vec2 FR,Vec2 RR,Vec2 BR,   Vec2 FL,Vec2 LL,Vec2 BL,  Vec2 DesiredDirection  );
		void ComputeWeight_ISTP(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x04]) ];
			GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x05]) ];
			Vec3 vVelocity00=rGHLMG.m_arrBSAnimations[0x00].m_qVelocity;
			Vec3 vVelocity01=rGHLMG.m_arrBSAnimations[0x01].m_qVelocity;
			Vec3 vVelocity02=rGHLMG.m_arrBSAnimations[0x02].m_qVelocity;
			Vec3 vVelocity03=rGHLMG.m_arrBSAnimations[0x03].m_qVelocity;
			Vec3 vVelocity04=rGHLMG.m_arrBSAnimations[0x04].m_qVelocity;
			Vec3 vVelocity05=rGHLMG.m_arrBSAnimations[0x05].m_qVelocity;

			f32 length = lmg.m_BlendSpace.m_strafe.GetLength();
			if (length>1.0f) length=1.0f;

			Vec2 sFR = Vec2(vVelocity00);
			Vec2 sRR = Vec2(vVelocity01);
			Vec2 sBR = Vec2(vVelocity02);
			Vec2 sFL = Vec2(vVelocity03);
			Vec2 sRL = Vec2(vVelocity04);
			Vec2 sBL = Vec2(vVelocity05);
			IdleStepWeights6 blend = GetIdleStepWeights6(sFR,sRR,sBR, sFL,sRL,sBL, lmg.m_BlendSpace.m_strafe.GetNormalizedSafe() );

			lmg.m_fBlendWeight[0]=blend.fr*length;	
			lmg.m_fBlendWeight[1]=blend.rr*length;	
			lmg.m_fBlendWeight[2]=blend.br*length;	
			lmg.m_fBlendWeight[3]=blend.fl*length;	
			lmg.m_fBlendWeight[4]=blend.ll*length;	
			lmg.m_fBlendWeight[5]=blend.bl*length;	
			lmg.m_fBlendWeight[6]=1.0f-length;

#ifdef _DEBUG
			f32 fTotal=0.0f;
			for (uint32 i=0; i<7; i++)
				fTotal+=lmg.m_fBlendWeight[i];
			assert( fabsf(fTotal-1.0f)<0.005f );

			uint32 nExtrapolation1=0;
			for (uint32 i=0; i<7; i++)
				nExtrapolation1 |= uint32(lmg.m_fBlendWeight[i]<-0.2f);
			assert(nExtrapolation1==0);

			uint32 nExtrapolation2=0;
			for (uint32 i=0; i<7; i++)
				nExtrapolation2 |= uint32(lmg.m_fBlendWeight[i]>1.2f);
			assert(nExtrapolation2==0);
#endif
		}

		// [artemk] ISTP for tactical move
		void ComputeWeight_T_IS(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x04]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x05]) ];

			f32 length = lmg.m_BlendSpace.m_strafe.GetLength();
			if (length>1.0f) length=1.0f;

			//		Vec2 sFR = Vec2(rsubGAH00.m_vVelocity);
			//		Vec2 sRR = Vec2(rsubGAH01.m_vVelocity);
			//		Vec2 sBR = Vec2(rsubGAH02.m_vVelocity);
			//		Vec2 sFL = Vec2(rsubGAH03.m_vVelocity);
			//		Vec2 sRL = Vec2(rsubGAH04.m_vVelocity);
			//		Vec2 sBL = Vec2(rsubGAH05.m_vVelocity);
			Vec2 sFR=Vec2(rGHLMG.m_arrBSAnimations[0x00].m_qVelocity);
			Vec2 sRR=Vec2(rGHLMG.m_arrBSAnimations[0x01].m_qVelocity);
			Vec2 sBR=Vec2(rGHLMG.m_arrBSAnimations[0x02].m_qVelocity);
			Vec2 sFL=Vec2(rGHLMG.m_arrBSAnimations[0x03].m_qVelocity);
			Vec2 sRL=Vec2(rGHLMG.m_arrBSAnimations[0x04].m_qVelocity);
			Vec2 sBL=Vec2(rGHLMG.m_arrBSAnimations[0x05].m_qVelocity);


			IdleStepWeights6 blend = GetIdleStepWeights6(sFR,sRR,sBR, sFL,sRL,sBL, lmg.m_BlendSpace.m_strafe.GetNormalizedSafe() );

			lmg.m_fBlendWeight[0]=blend.fr*length;	
			lmg.m_fBlendWeight[1]=blend.rr*length;	
			lmg.m_fBlendWeight[2]=blend.br*length;	
			lmg.m_fBlendWeight[3]=blend.fl*length;	
			lmg.m_fBlendWeight[4]=blend.ll*length;	
			lmg.m_fBlendWeight[5]=blend.bl*length;	
			lmg.m_fBlendWeight[6]=1.0f-length;

			float scale;
			if (!pAnimationSet->m_CharEditMode)
			{
				scale = GetParamScale(lmg);
			}
			else
			{
				scale = 0.9f + (lmg.m_BlendSpace.m_speed * 0.5f + 0.5f) * 0.2f;
				scale = clamp(scale, 0.9f, 1.1f);
			}

			if (scale > 1.0f /*test stuff*/ /*&& gEnv->pConsole->GetCVar("ca_testInt")->GetIVal()*/)
			{
				float t = (scale - 1.0f) / (1.1f - 1.0f);
				t = clamp(t, 0.0f, 1.0f);

				for (int i = 0; i < 7; i++)
					lmg.m_fBlendWeight[i+7] = lmg.m_fBlendWeight[i] * t;

				for (int i = 0; i < 7; i++)
					lmg.m_fBlendWeight[i] *= (1.0f-t);
			}
		}

		// [artemk] Tactical idle aiming lmg
		void ComputeWeight_T_IA(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			float scale;
			if (!pAnimationSet->m_CharEditMode)
			{
				scale = GetParamScale(lmg);
			}
			else
			{
				scale = 0.9f + (lmg.m_BlendSpace.m_speed * 0.5f + 0.5f) * 0.2f;
				scale = clamp(scale, 0.9f, 1.1f);
			}

			if (scale <= 1.0f)
			{
				lmg.m_fBlendWeight[0] = 1.0f;
				lmg.m_fBlendWeight[1] = 0.0f;
			}
			else
			{
				float t = (scale - 1.0f) / (1.1f - 1.0f);
				t = clamp(t, 0.0f, 1.0f);
				lmg.m_fBlendWeight[0] = 1.0f - t;
				lmg.m_fBlendWeight[1] = t;
			}
		}

		void ComputeWeight_TRN1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	t = lmg.m_BlendSpace.m_turn*1;
			if (t<0)
			{
				if (t<-0.5f)
				{
					t=t+0.5f;
					lmg.m_fBlendWeight[4]=-t*2;		//left 90
					lmg.m_fBlendWeight[3]=1.0f-lmg.m_fBlendWeight[4];	//middle
				}
				else
				{
					lmg.m_fBlendWeight[3]=-t*2;		//left 90
					lmg.m_fBlendWeight[2]=1.0f-lmg.m_fBlendWeight[3];	//middle
				}
			}
			else
			{
				if (t<0.5f)
				{
					lmg.m_fBlendWeight[1]=t*2;    //right 90
					lmg.m_fBlendWeight[2]=1-t*2;  //middle
				}
				else
				{
					t=t-0.5f;
					lmg.m_fBlendWeight[0]=t*2;    //right 180
					lmg.m_fBlendWeight[1]=1-t*2;  //left 90
				}
			}			

			f32 fColor[4] = {1,1,0,1};
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"r180: %f", lmg.m_fBlendWeight[0] ); g_YLine+=0x0d;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"r090: %f", lmg.m_fBlendWeight[1] ); g_YLine+=0x0d;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"f00:  %f", lmg.m_fBlendWeight[2] ); g_YLine+=0x0d;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"l090: %f", lmg.m_fBlendWeight[3] ); g_YLine+=0x0d;
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false,"l180: %f", lmg.m_fBlendWeight[4] ); g_YLine+=0x0d;
		}

		void ComputeWeight_STF1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			//GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			//GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			//GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			//GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			Vec3 vVelocity00=rGHLMG.m_arrBSAnimations[0x00].m_qVelocity;
			Vec3 vVelocity01=rGHLMG.m_arrBSAnimations[0x01].m_qVelocity;
			Vec3 vVelocity02=rGHLMG.m_arrBSAnimations[0x02].m_qVelocity;
			Vec3 vVelocity03=rGHLMG.m_arrBSAnimations[0x03].m_qVelocity;

			Vec2 sF = Vec2(vVelocity00);
			Vec2 sL = Vec2(vVelocity01);
			Vec2 sB = Vec2(vVelocity02);
			Vec2 sR = Vec2(vVelocity03);
			StrafeWeights4 blend = GetStrafingWeights4(sF,sL,sB,sR, lmg.m_BlendSpace.m_strafe);

			f32 t = lmg.m_BlendSpace.m_strafe.GetLength();

			lmg.m_fBlendWeight[0]=blend.f*t + 0.25f*(1.0f-t);
			lmg.m_fBlendWeight[1]=blend.l*t + 0.25f*(1.0f-t);	
			lmg.m_fBlendWeight[2]=blend.b*t + 0.25f*(1.0f-t);
			lmg.m_fBlendWeight[3]=blend.r*t + 0.25f*(1.0f-t);	
		}

		void ComputeWeight_STF2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			uint32 poffset=0;
			BlendWeights_STF2 stf2;	ComputeWeight_STF2( pAnimationSet, lmg,poffset, stf2, rGHLMG );

			lmg.m_fBlendWeight[0+0]=stf2.ff;	
			lmg.m_fBlendWeight[1+0]=stf2.fl;	
			lmg.m_fBlendWeight[2+0]=stf2.fb;
			lmg.m_fBlendWeight[3+0]=stf2.fr;	

			lmg.m_fBlendWeight[0+4]=stf2.sf;	
			lmg.m_fBlendWeight[1+4]=stf2.sl;	
			lmg.m_fBlendWeight[2+4]=stf2.sb;
			lmg.m_fBlendWeight[3+4]=stf2.sr;	
		}

		void ComputeWeight_SUD2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			uint32 uoffset=0;
			BlendWeights_STF2 ustf2;	ComputeWeight_STF2( pAnimationSet, lmg,uoffset, ustf2, rGHLMG );
			uint32 poffset=8;
			BlendWeights_STF2 pstf2;	ComputeWeight_STF2( pAnimationSet, lmg,poffset, pstf2, rGHLMG );
			uint32 doffset=16;
			BlendWeights_STF2 dstf2;	ComputeWeight_STF2( pAnimationSet, lmg,doffset, dstf2, rGHLMG );

			f32 uh=0,fw=0,dh=0;
			f32	q = lmg.m_BlendSpace.m_slope;
			if (q>0) { uh=q;	fw=1-q;	}
			else { fw=1+q;	dh=1-(q+1);	}

			lmg.m_fBlendWeight[0+0x00]=ustf2.ff*uh;	
			lmg.m_fBlendWeight[1+0x00]=ustf2.fl*uh;	
			lmg.m_fBlendWeight[2+0x00]=ustf2.fb*uh;
			lmg.m_fBlendWeight[3+0x00]=ustf2.fr*uh;	
			lmg.m_fBlendWeight[4+0x00]=ustf2.sf*uh;	
			lmg.m_fBlendWeight[5+0x00]=ustf2.sl*uh;	
			lmg.m_fBlendWeight[6+0x00]=ustf2.sb*uh;
			lmg.m_fBlendWeight[7+0x00]=ustf2.sr*uh;	

			lmg.m_fBlendWeight[0+0x08]=pstf2.ff*fw;	
			lmg.m_fBlendWeight[1+0x08]=pstf2.fl*fw;	
			lmg.m_fBlendWeight[2+0x08]=pstf2.fb*fw;
			lmg.m_fBlendWeight[3+0x08]=pstf2.fr*fw;	
			lmg.m_fBlendWeight[4+0x08]=pstf2.sf*fw;	
			lmg.m_fBlendWeight[5+0x08]=pstf2.sl*fw;	
			lmg.m_fBlendWeight[6+0x08]=pstf2.sb*fw;
			lmg.m_fBlendWeight[7+0x08]=pstf2.sr*fw;	

			lmg.m_fBlendWeight[0+0x10]=dstf2.ff*dh;	
			lmg.m_fBlendWeight[1+0x10]=dstf2.fl*dh;	
			lmg.m_fBlendWeight[2+0x10]=dstf2.fb*dh;
			lmg.m_fBlendWeight[3+0x10]=dstf2.fr*dh;	
			lmg.m_fBlendWeight[4+0x10]=dstf2.sf*dh;	
			lmg.m_fBlendWeight[5+0x10]=dstf2.sl*dh;	
			lmg.m_fBlendWeight[6+0x10]=dstf2.sb*dh;
			lmg.m_fBlendWeight[7+0x10]=dstf2.sr*dh;	
		}

		void ComputeWeight_S__1(SParametric& lmg, const CAnimationSet* pAnimationSet, GlobalAnimationHeaderCAF* parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x04]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x05]) ];

			//	Vec2 sF		= Vec2(rsubGAH00.m_vVelocity);
			//	Vec2 sFL	= Vec2(rsubGAH01.m_vVelocity);
			//	Vec2 sL		= Vec2(rsubGAH02.m_vVelocity);
			//	Vec2 sB		= Vec2(rsubGAH03.m_vVelocity);
			//	Vec2 sBR	= Vec2(rsubGAH04.m_vVelocity);
			//	Vec2 sR		= Vec2(rsubGAH05.m_vVelocity);
			Vec2 sF =Vec2(rGHLMG.m_arrBSAnimations[0x00].m_qVelocity);
			Vec2 sFL=Vec2(rGHLMG.m_arrBSAnimations[0x01].m_qVelocity);
			Vec2 sL =Vec2(rGHLMG.m_arrBSAnimations[0x02].m_qVelocity);
			Vec2 sB =Vec2(rGHLMG.m_arrBSAnimations[0x03].m_qVelocity);
			Vec2 sBR=Vec2(rGHLMG.m_arrBSAnimations[0x04].m_qVelocity);
			Vec2 sR =Vec2(rGHLMG.m_arrBSAnimations[0x05].m_qVelocity);
			StrafeWeights6 blend = GetStrafingWeights6(sF,sFL,sL, sB,sBR,sR, lmg.m_BlendSpace.m_strafe );

			f32 t = lmg.m_BlendSpace.m_strafe.GetLength();
			f32 p =	(1.0f/6.0f);
			blend.f		=	blend.f*t		+ p*(1.0f-t);
			blend.fl	=	blend.fl*t	+ p*(1.0f-t);
			blend.l		=	blend.l*t		+ p*(1.0f-t);	
			blend.b		=	blend.b*t		+ p*(1.0f-t);
			blend.br	=	blend.br*t	+ p*(1.0f-t);
			blend.r		=	blend.r*t		+ p*(1.0f-t);	

			lmg.m_fBlendWeight[0] = blend.f;	
			lmg.m_fBlendWeight[1] = blend.fl;	
			lmg.m_fBlendWeight[2] = blend.l;	
			lmg.m_fBlendWeight[3] = blend.b;	
			lmg.m_fBlendWeight[4] = blend.br;	
			lmg.m_fBlendWeight[5] = blend.r;	
		}


		void ComputeWeight_M__1(SParametric& lmg, const CAnimationSet* pAnimationSet, GlobalAnimationHeaderCAF* parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			//		GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x04]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x05]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH06 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x06]) ];
			//		GlobalAnimationHeaderCAF& rsubGAH07 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x07]) ];

			//		Vec2 sF		= Vec2(rsubGAH00.m_vVelocity);
			//		Vec2 sFL	= Vec2(rsubGAH01.m_vVelocity);
			//		Vec2 sL		= Vec2(rsubGAH02.m_vVelocity);
			//		Vec2 sLB	= Vec2(rsubGAH03.m_vVelocity);
			//		Vec2 sB		= Vec2(rsubGAH04.m_vVelocity);
			//		Vec2 sBR	= Vec2(rsubGAH05.m_vVelocity);
			//		Vec2 sR		= Vec2(rsubGAH06.m_vVelocity);
			//		Vec2 sRF	= Vec2(rsubGAH07.m_vVelocity);

			Vec2 sF =Vec2(rGHLMG.m_arrBSAnimations[0x00].m_qVelocity);
			Vec2 sFL=Vec2(rGHLMG.m_arrBSAnimations[0x01].m_qVelocity);
			Vec2 sL =Vec2(rGHLMG.m_arrBSAnimations[0x02].m_qVelocity);
			Vec2 sLB=Vec2(rGHLMG.m_arrBSAnimations[0x03].m_qVelocity);
			Vec2 sB =Vec2(rGHLMG.m_arrBSAnimations[0x04].m_qVelocity);
			Vec2 sBR=Vec2(rGHLMG.m_arrBSAnimations[0x05].m_qVelocity);
			Vec2 sR =Vec2(rGHLMG.m_arrBSAnimations[0x06].m_qVelocity);
			Vec2 sRF=Vec2(rGHLMG.m_arrBSAnimations[0x07].m_qVelocity);

			StrafeWeights8 blend = GetStrafingWeights8(sF,sFL,sL,sLB, sB,sBR,sR,sRF, lmg.m_BlendSpace.m_strafe );

			f32 t = lmg.m_BlendSpace.m_strafe.GetLength();
			f32 p =	(1.0f/8.0f);
			blend.f		=	blend.f*t		+ p*(1.0f-t);
			blend.fl	=	blend.fl*t	+ p*(1.0f-t);
			blend.l		=	blend.l*t		+ p*(1.0f-t);	
			blend.lb	=	blend.lb*t	+ p*(1.0f-t);	
			blend.b		=	blend.b*t		+ p*(1.0f-t);
			blend.br	=	blend.br*t	+ p*(1.0f-t);
			blend.r		=	blend.r*t		+ p*(1.0f-t);	
			blend.rf	=	blend.rf*t	+ p*(1.0f-t);	

			lmg.m_fBlendWeight[0] = blend.f;	
			lmg.m_fBlendWeight[1] = blend.fl;	
			lmg.m_fBlendWeight[2] = blend.l;	
			lmg.m_fBlendWeight[3] = blend.lb;	
			lmg.m_fBlendWeight[4] = blend.b;	
			lmg.m_fBlendWeight[5] = blend.br;	
			lmg.m_fBlendWeight[6] = blend.r;	
			lmg.m_fBlendWeight[7] = blend.rf;	
		}



		void ComputeWeight_T_WS(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			//	GlobalAnimationHeaderCAF& rsubGAH00 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x00]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH01 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x01]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH02 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x02]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH03 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x03]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH04 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x04]) ];
			//	GlobalAnimationHeaderCAF& rsubGAH05 = parrGlobalAnimations[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0x05]) ];
			//	Vec2 sF	= Vec2(rsubGAH00.m_vVelocity);
			//	Vec2 sFL= Vec2(rsubGAH01.m_vVelocity);
			//	Vec2 sL	= Vec2(rsubGAH02.m_vVelocity);
			//	Vec2 sB	= Vec2(rsubGAH03.m_vVelocity);
			//	Vec2 sBR= Vec2(rsubGAH04.m_vVelocity);
			//	Vec2 sR	= Vec2(rsubGAH05.m_vVelocity);
			Vec2 sF =Vec2(rGHLMG.m_arrBSAnimations[0x00].m_qVelocity);
			Vec2 sFL=Vec2(rGHLMG.m_arrBSAnimations[0x01].m_qVelocity);
			Vec2 sL =Vec2(rGHLMG.m_arrBSAnimations[0x02].m_qVelocity);
			Vec2 sB =Vec2(rGHLMG.m_arrBSAnimations[0x04].m_qVelocity);
			Vec2 sBR=Vec2(rGHLMG.m_arrBSAnimations[0x05].m_qVelocity);
			Vec2 sR =Vec2(rGHLMG.m_arrBSAnimations[0x06].m_qVelocity);
			StrafeWeights6 blend = GetStrafingWeights6(sF,sFL,sL, sB,sBR,sR, lmg.m_BlendSpace.m_strafe );

			f32 l = lmg.m_BlendSpace.m_strafe.GetLength();
			f32 p =	(1.0f/6.0f);
			blend.f		=	blend.f*l		+ p*(1.0f-l);
			blend.fl	=	blend.fl*l	+ p*(1.0f-l);
			blend.l		=	blend.l*l		+ p*(1.0f-l);	
			blend.b		=	blend.b*l		+ p*(1.0f-l);
			blend.br	=	blend.br*l	+ p*(1.0f-l);
			blend.r		=	blend.r*l		+ p*(1.0f-l);	

			lmg.m_fBlendWeight[0] = blend.f;	
			lmg.m_fBlendWeight[1] = blend.fl;	
			lmg.m_fBlendWeight[2] = blend.l;	
			lmg.m_fBlendWeight[3] = blend.b;	
			lmg.m_fBlendWeight[4] = blend.br;
			lmg.m_fBlendWeight[5] = blend.r;

			float scale;
			if (!pAnimationSet->m_CharEditMode)
			{
				scale = GetParamScale(lmg);
			}
			else
			{
				scale = 0.9f + (lmg.m_BlendSpace.m_speed * 0.5f + 0.5f) * 0.2f;
				scale = clamp(scale, 0.9f, 1.1f);
			}

			if (scale > 1.0f /*test stuff*/ /*&& gEnv->pConsole->GetCVar("ca_testInt")->GetIVal()*/)
			{
				float t = (scale - 1.0f) / (1.1f - 1.0f);
				t = clamp(t, 0.0f, 1.0f);

				for (int i = 0; i < 6; i++)
					lmg.m_fBlendWeight[i+6] = lmg.m_fBlendWeight[i] * t;

				for (int i = 0; i < 6; i++)
					lmg.m_fBlendWeight[i] *= (1.0f-t);
			}
		}

		void ComputeWeight_S__2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			uint32 poffset=0;
			BlendWeights_S2 s2;	ComputeWeight_S2( pAnimationSet, lmg,poffset, s2, rGHLMG  );

			lmg.m_fBlendWeight[0+0]=s2.ff;	
			lmg.m_fBlendWeight[1+0]=s2.ffl;	
			lmg.m_fBlendWeight[2+0]=s2.fl;	
			lmg.m_fBlendWeight[3+0]=s2.fb;
			lmg.m_fBlendWeight[4+0]=s2.fbr;
			lmg.m_fBlendWeight[5+0]=s2.fr;	

			lmg.m_fBlendWeight[0+6]=s2.sf;	
			lmg.m_fBlendWeight[1+6]=s2.sfl;	
			lmg.m_fBlendWeight[2+6]=s2.sl;	
			lmg.m_fBlendWeight[3+6]=s2.sb;
			lmg.m_fBlendWeight[4+6]=s2.sbr;
			lmg.m_fBlendWeight[5+6]=s2.sr;	
		}

		void ComputeWeight_ST_2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{	
			uint32 poffset=0;
			BlendWeights_ST2 st2;	ComputeWeight_ST2( pAnimationSet, lmg,poffset, st2, rGHLMG );

			lmg.m_fBlendWeight[poffset+0x00]=st2.ff;	//fast forward speed
			lmg.m_fBlendWeight[poffset+0x01]=st2.ffl;	
			lmg.m_fBlendWeight[poffset+0x02]=st2.fl;	
			lmg.m_fBlendWeight[poffset+0x03]=st2.fb;	
			lmg.m_fBlendWeight[poffset+0x04]=st2.fbr;	
			lmg.m_fBlendWeight[poffset+0x05]=st2.fr;	

			lmg.m_fBlendWeight[poffset+0x06]=st2.mf;		//middle forward speed	

			lmg.m_fBlendWeight[poffset+0x07]=st2.sf;	//slow forward speed
			lmg.m_fBlendWeight[poffset+0x08]=st2.sfl;	
			lmg.m_fBlendWeight[poffset+0x09]=st2.sl;	
			lmg.m_fBlendWeight[poffset+0x0a]=st2.sb;	
			lmg.m_fBlendWeight[poffset+0x0b]=st2.sbr;	
			lmg.m_fBlendWeight[poffset+0x0c]=st2.sr;	

			lmg.m_fBlendWeight[poffset+0x0d]=st2.fftl;	//left
			lmg.m_fBlendWeight[poffset+0x0e]=st2.fftr;	//right
			lmg.m_fBlendWeight[poffset+0x0f]=st2.sftl;	//left
			lmg.m_fBlendWeight[poffset+0x10]=st2.sftr;	//right
		}

		void ComputeWeight_S_H2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{

			f32 uh=0,fw=0,dh=0;
			f32	q = lmg.m_BlendSpace.m_slope;
			if (q>0) { uh=q;	fw=1-q;	}
			else { fw=1+q;	dh=1-(q+1);	}

			uint32 uoffset=0;
			BlendWeights_STF2 stu2;	ComputeWeight_STF2( pAnimationSet, lmg,uoffset, stu2, rGHLMG );
			lmg.m_fBlendWeight[uoffset+0x00]=stu2.ff*uh;	
			lmg.m_fBlendWeight[uoffset+0x01]=stu2.fl*uh;	
			lmg.m_fBlendWeight[uoffset+0x02]=stu2.fb*uh;	
			lmg.m_fBlendWeight[uoffset+0x03]=stu2.fr*uh;	
			lmg.m_fBlendWeight[uoffset+0x04]=stu2.sf*uh;	
			lmg.m_fBlendWeight[uoffset+0x05]=stu2.sl*uh;	
			lmg.m_fBlendWeight[uoffset+0x06]=stu2.sb*uh;	
			lmg.m_fBlendWeight[uoffset+0x07]=stu2.sr*uh;	

			uint32 poffset=8;
			BlendWeights_S2 s2;	ComputeWeight_S2( pAnimationSet, lmg,poffset, s2, rGHLMG );
			lmg.m_fBlendWeight[poffset+0x00]=s2.ff*fw;	//fast forward speed
			lmg.m_fBlendWeight[poffset+0x01]=s2.ffl*fw;	
			lmg.m_fBlendWeight[poffset+0x02]=s2.fl*fw;	
			lmg.m_fBlendWeight[poffset+0x03]=s2.fb*fw;	
			lmg.m_fBlendWeight[poffset+0x04]=s2.fbr*fw;	
			lmg.m_fBlendWeight[poffset+0x05]=s2.fr*fw;	

			lmg.m_fBlendWeight[poffset+0x06]=s2.sf*fw;	//slow forward speed
			lmg.m_fBlendWeight[poffset+0x07]=s2.sfl*fw;	
			lmg.m_fBlendWeight[poffset+0x08]=s2.sl*fw;	
			lmg.m_fBlendWeight[poffset+0x09]=s2.sb*fw;	
			lmg.m_fBlendWeight[poffset+0x0a]=s2.sbr*fw;	
			lmg.m_fBlendWeight[poffset+0x0b]=s2.sr*fw;	

			uint32 doffset=0x08+0x0c;
			BlendWeights_STF2 std2;	ComputeWeight_STF2( pAnimationSet, lmg,doffset, std2,rGHLMG);
			lmg.m_fBlendWeight[doffset+0x00]=std2.ff*dh;	
			lmg.m_fBlendWeight[doffset+0x01]=std2.fl*dh;	
			lmg.m_fBlendWeight[doffset+0x02]=std2.fb*dh;	
			lmg.m_fBlendWeight[doffset+0x03]=std2.fr*dh;	
			lmg.m_fBlendWeight[doffset+0x04]=std2.sf*dh;	
			lmg.m_fBlendWeight[doffset+0x05]=std2.sl*dh;	
			lmg.m_fBlendWeight[doffset+0x06]=std2.sb*dh;	
			lmg.m_fBlendWeight[doffset+0x07]=std2.sr*dh;	
		}

		void ComputeWeight_STH2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{

			f32 uh=0,fw=0,dh=0;
			f32	q = lmg.m_BlendSpace.m_slope;
			if (q>0) { uh=q;	fw=1-q;	}
			else { fw=1+q;	dh=1-(q+1);	}

			uint32 uoffset=0;
			BlendWeights_STF2 stu2;	ComputeWeight_STF2( pAnimationSet, lmg,uoffset, stu2, rGHLMG );
			lmg.m_fBlendWeight[uoffset+0x00]=stu2.ff*uh;	
			lmg.m_fBlendWeight[uoffset+0x01]=stu2.fl*uh;	
			lmg.m_fBlendWeight[uoffset+0x02]=stu2.fb*uh;	
			lmg.m_fBlendWeight[uoffset+0x03]=stu2.fr*uh;	

			lmg.m_fBlendWeight[uoffset+0x04]=stu2.sf*uh;	
			lmg.m_fBlendWeight[uoffset+0x05]=stu2.sl*uh;	
			lmg.m_fBlendWeight[uoffset+0x06]=stu2.sb*uh;	
			lmg.m_fBlendWeight[uoffset+0x07]=stu2.sr*uh;	

			uint32 poffset=8;
			BlendWeights_ST2 st2;	ComputeWeight_ST2( pAnimationSet, lmg,poffset, st2, rGHLMG  );

			lmg.m_fBlendWeight[poffset+0x00]=st2.ff*fw;	//fast forward speed
			lmg.m_fBlendWeight[poffset+0x01]=st2.ffl*fw;	
			lmg.m_fBlendWeight[poffset+0x02]=st2.fl*fw;	
			lmg.m_fBlendWeight[poffset+0x03]=st2.fb*fw;	
			lmg.m_fBlendWeight[poffset+0x04]=st2.fbr*fw;	
			lmg.m_fBlendWeight[poffset+0x05]=st2.fr*fw;	

			lmg.m_fBlendWeight[poffset+0x06]=st2.mf*fw;		//middle forward speed	

			lmg.m_fBlendWeight[poffset+0x07]=st2.sf*fw;	//slow forward speed
			lmg.m_fBlendWeight[poffset+0x08]=st2.sfl*fw;	
			lmg.m_fBlendWeight[poffset+0x09]=st2.sl*fw;	
			lmg.m_fBlendWeight[poffset+0x0a]=st2.sb*fw;	
			lmg.m_fBlendWeight[poffset+0x0b]=st2.sbr*fw;	
			lmg.m_fBlendWeight[poffset+0x0c]=st2.sr*fw;	

			lmg.m_fBlendWeight[poffset+0x0d]=st2.fftl*fw;	//left
			lmg.m_fBlendWeight[poffset+0x0e]=st2.fftr*fw;	//right
			lmg.m_fBlendWeight[poffset+0x0f]=st2.sftl*fw;	//left
			lmg.m_fBlendWeight[poffset+0x10]=st2.sftr*fw;	//right

			uint32 doffset=0x08+0x11;
			BlendWeights_STF2 std2;	ComputeWeight_STF2( pAnimationSet, lmg,doffset, std2, rGHLMG  );
			lmg.m_fBlendWeight[doffset+0x00]=std2.ff*dh;	
			lmg.m_fBlendWeight[doffset+0x01]=std2.fl*dh;	
			lmg.m_fBlendWeight[doffset+0x02]=std2.fb*dh;	
			lmg.m_fBlendWeight[doffset+0x03]=std2.fr*dh;	

			lmg.m_fBlendWeight[doffset+0x04]=std2.sf*dh;	
			lmg.m_fBlendWeight[doffset+0x05]=std2.sl*dh;	
			lmg.m_fBlendWeight[doffset+0x06]=std2.sb*dh;	
			lmg.m_fBlendWeight[doffset+0x07]=std2.sr*dh;	
		}

		SPU_NO_INLINE void ComputeWeight_STHX(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF* parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{

			f32 uh=0,fw=0,dh=0;
			f32	q = lmg.m_BlendSpace.m_slope;
			if (q>0) { uh=q;	fw=1-q;	}
			else { fw=1+q;	dh=1-(q+1);	}

			uint32 uoffset=0;
			BlendWeights_STF2 stu2;	ComputeWeight_STF2( pAnimationSet, lmg,uoffset, stu2, rGHLMG );
			lmg.m_fBlendWeight[uoffset+0x00]=stu2.ff*uh;	
			lmg.m_fBlendWeight[uoffset+0x01]=stu2.fl*uh;	
			lmg.m_fBlendWeight[uoffset+0x02]=stu2.fb*uh;	
			lmg.m_fBlendWeight[uoffset+0x03]=stu2.fr*uh;	

			lmg.m_fBlendWeight[uoffset+0x04]=stu2.sf*uh;	
			lmg.m_fBlendWeight[uoffset+0x05]=stu2.sl*uh;	
			lmg.m_fBlendWeight[uoffset+0x06]=stu2.sb*uh;	
			lmg.m_fBlendWeight[uoffset+0x07]=stu2.sr*uh;	

			uint32 poffset=8;
			BlendWeights_STX stx;	ComputeWeight_STX( pAnimationSet, lmg,poffset, stx, rGHLMG );

			lmg.m_fBlendWeight[poffset+0x00]=stx.ff*fw;	//fast forward speed
			lmg.m_fBlendWeight[poffset+0x01]=stx.fl*fw;	
			lmg.m_fBlendWeight[poffset+0x02]=stx.fb*fw;	
			lmg.m_fBlendWeight[poffset+0x03]=stx.fr*fw;	

			lmg.m_fBlendWeight[poffset+0x04]=stx.mf*fw;		//middle forward speed	

			lmg.m_fBlendWeight[poffset+0x05]=stx.sf*fw;	//slow forward speed
			lmg.m_fBlendWeight[poffset+0x06]=stx.sl*fw;	
			lmg.m_fBlendWeight[poffset+0x07]=stx.sb*fw;	
			lmg.m_fBlendWeight[poffset+0x08]=stx.sr*fw;	

			lmg.m_fBlendWeight[poffset+0x09]=stx.fftl*fw;	//left
			lmg.m_fBlendWeight[poffset+0x0a]=stx.fftr*fw;	//right
			lmg.m_fBlendWeight[poffset+0x0b]=stx.sftl*fw;	//left
			lmg.m_fBlendWeight[poffset+0x0c]=stx.sftr*fw;	//right

			uint32 doffset=0x08+0x0d;
			BlendWeights_STF2 std2;	ComputeWeight_STF2( pAnimationSet, lmg,doffset, std2, rGHLMG   );
			lmg.m_fBlendWeight[doffset+0x00]=std2.ff*dh;	
			lmg.m_fBlendWeight[doffset+0x01]=std2.fl*dh;	
			lmg.m_fBlendWeight[doffset+0x02]=std2.fb*dh;	
			lmg.m_fBlendWeight[doffset+0x03]=std2.fr*dh;	

			lmg.m_fBlendWeight[doffset+0x04]=std2.sf*dh;	
			lmg.m_fBlendWeight[doffset+0x05]=std2.sl*dh;	
			lmg.m_fBlendWeight[doffset+0x06]=std2.sb*dh;	
			lmg.m_fBlendWeight[doffset+0x07]=std2.sr*dh;	
		}

		void ComputeWeight_WFW2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	SpeedWeight = (lmg.m_BlendSpace.m_speed+1)*0.5f;
			lmg.m_fBlendWeight[0]=1-SpeedWeight;
			lmg.m_fBlendWeight[1]=SpeedWeight;
		}

		void ComputeWeight_RFW3(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	t = lmg.m_BlendSpace.m_speed;
			if (t<0)
			{
				lmg.m_fBlendWeight[0]=1-(t+1);
				lmg.m_fBlendWeight[1]=t+1;
			}
			else
			{
				lmg.m_fBlendWeight[0]=0;
				lmg.m_fBlendWeight[1]=(1-t);
			}
		}

		void ComputeWeight_FLR1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			f32	t = lmg.m_BlendSpace.m_turn;
			if (t<0)
			{
				lmg.m_fBlendWeight[0]=-t;   //left
				lmg.m_fBlendWeight[1]=1+t;  //middle
			}
			else
			{
				lmg.m_fBlendWeight[1]=1-t;	//middle
				lmg.m_fBlendWeight[2]=t;		//right
			}			
		}

		void ComputeWeight_FLR2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF* parrGlobalCAFs, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			Vec2 FL=Vec2(rGlobalAnimHeader.m_arrBSAnimations[0].m_Position);	//fast	
			Vec2 FF=Vec2(rGlobalAnimHeader.m_arrBSAnimations[1].m_Position);	//fast	
			Vec2 FR=Vec2(rGlobalAnimHeader.m_arrBSAnimations[2].m_Position);	//fast	
			Vec2 SL=Vec2(rGlobalAnimHeader.m_arrBSAnimations[3].m_Position);	//slow	
			Vec2 SF=Vec2(rGlobalAnimHeader.m_arrBSAnimations[4].m_Position);	//slow	
			Vec2 SR=Vec2(rGlobalAnimHeader.m_arrBSAnimations[5].m_Position);	//slow	

			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);
			LocomotionWeights6 w = ComputeWeightLoco6( p, FL,FF,FR,  SL,SF,SR );
			lmg.m_fBlendWeight[0]=w.fl;	lmg.m_fBlendWeight[1]=w.ff;	lmg.m_fBlendWeight[2]=w.fr;	
			lmg.m_fBlendWeight[3]=w.sl;	lmg.m_fBlendWeight[4]=w.sf;	lmg.m_fBlendWeight[5]=w.sr;	
		}





		SPU_NO_INLINE void ComputeWeight_FLR3(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalCAFs, GlobalAnimationHeaderLMG& rGHLMG2222)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rLMG = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];
			uint32 numExamples = rLMG.m_arrBSAnimations.size();

			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);


			Vec2 FL=Vec2(-1,+1);	//sprint	
			Vec2 FF=Vec2( 0,+1);	//sprint	
			Vec2 FR=Vec2(+1,+1);	//sprint	
			Vec2 MF=Vec2( 0, 0);	//fast forward	
			Vec2 SL=Vec2(-1,-1);	//slow	
			Vec2 SF=Vec2( 0,-1);	//slow	
			Vec2 SR=Vec2(+1,-1);	//slow	

			GlobalAnimationHeaderCAF& rCAF00 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[0]) ]; 
			GlobalAnimationHeaderCAF& rCAF01 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[1]) ]; 
			GlobalAnimationHeaderCAF& rCAF02 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[2]) ];

			GlobalAnimationHeaderCAF& rCAF03 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[3]) ]; 

			GlobalAnimationHeaderCAF& rCAF04 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[4]) ]; 
			GlobalAnimationHeaderCAF& rCAF05 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[5]) ]; 
			const GlobalAnimationHeaderCAF& rCAF06 = parrGlobalCAFs[ pAnimationSet->GetGlobalIDByAnimID_Fast(lmg.m_nAnimID[6]) ]; 

			//f32 L_fast=rCAF00.m_fMoveSpeed;	
			f32 F_fast=rCAF01.m_fMoveSpeed;	
			//f32 R_fast=rCAF02.m_fMoveSpeed;	

			f32 F_mid	=rCAF03.m_fMoveSpeed;

			//f32 L_slow=rCAF04.m_fMoveSpeed;	
			f32 F_slow=rCAF05.m_fMoveSpeed;	
			//f32 R_slow=rCAF06.m_fMoveSpeed;	

			f32 f0 = F_mid	-F_slow;
			f32 f1 = F_fast -F_slow;
			MF.y = (f0/f1)*2-1;

			LocomotionWeights7 w = ComputeWeightLoco7( p, FL,FF,FR, MF, SL,SF,SR );
			lmg.m_fBlendWeight[0]=w.fl;	lmg.m_fBlendWeight[1]=w.ff;	lmg.m_fBlendWeight[2]=w.fr;	
			lmg.m_fBlendWeight[3]=w.mf;	
			lmg.m_fBlendWeight[4]=w.sl;	lmg.m_fBlendWeight[5]=w.sf;	lmg.m_fBlendWeight[6]=w.sr;	
		}

		//-------------------------------------------------------------------

		void ComputeWeight_UDH1(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{

			f32 uh=0,fw=0,dh=0;
			f32	t = lmg.m_BlendSpace.m_slope;
			if (t>0)
			{
				uh=t;	fw=(1-t);
			}
			else
			{
				fw=t+1;	dh=1-(t+1);
			}

			f32 R=0,F=0,L=0;	
			t = lmg.m_BlendSpace.m_turn;
			if (t<0)
			{
				R=1-(t+1); F=t+1;
			}
			else
			{
				F=1-t; L=t;
			}			

			lmg.m_fBlendWeight[0]=R*uh;
			lmg.m_fBlendWeight[1]=F*uh;
			lmg.m_fBlendWeight[2]=L*uh;

			lmg.m_fBlendWeight[3]=R*fw;
			lmg.m_fBlendWeight[4]=F*fw;
			lmg.m_fBlendWeight[5]=L*fw;

			lmg.m_fBlendWeight[6]=R*dh;
			lmg.m_fBlendWeight[7]=F*dh;
			lmg.m_fBlendWeight[8]=L*dh;
		}

		SPU_NO_INLINE void ComputeWeight_UDH2(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			f32 uh=0;
			f32 fw=0;
			f32 dh=0;
			f32	t = lmg.m_BlendSpace.m_slope;
			if (t>0)
			{
				uh=t;
				fw=(1-t);
			}
			else
			{
				fw=t+1;
				dh=1-(t+1);
			}

			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);

			Vec3 bs06=rGlobalAnimHeader.m_arrBSAnimations[0x06].m_Position;		
			Vec3 bs07=rGlobalAnimHeader.m_arrBSAnimations[0x07].m_Position;		
			Vec3 bs08=rGlobalAnimHeader.m_arrBSAnimations[0x08].m_Position;		

			Vec3 bs09=rGlobalAnimHeader.m_arrBSAnimations[0x09].m_Position;		
			Vec3 bs0a=rGlobalAnimHeader.m_arrBSAnimations[0x0a].m_Position;		
			Vec3 bs0b=rGlobalAnimHeader.m_arrBSAnimations[0x0b].m_Position;		

			Vec2 p06=Vec2(bs06.x,bs06.y);		Vec2 p07=Vec2(bs07.x,bs07.y);		Vec2 p08=Vec2(bs08.x,bs08.y);
			Vec2 p09=Vec2(bs09.x,bs09.y);		Vec2 p0a=Vec2(bs0a.x,bs0a.y);		Vec2 p0b=Vec2(bs0b.x,bs0b.y);

			if (lmg.m_BlendSpace.m_turn<0)
			{
				//left side
				Vec4 w;
				ComputeWeight4(w, p, p09,p0a,p07,p06);
				lmg.m_fBlendWeight[0+ 0]=w.w*uh;	lmg.m_fBlendWeight[1+ 0]=w.z*uh;	
				lmg.m_fBlendWeight[3+ 0]=w.x*uh;	lmg.m_fBlendWeight[4+ 0]=w.y*uh;

				lmg.m_fBlendWeight[0+ 6]=w.w*fw;	lmg.m_fBlendWeight[1+ 6]=w.z*fw;	
				lmg.m_fBlendWeight[3+ 6]=w.x*fw;	lmg.m_fBlendWeight[4+ 6]=w.y*fw;

				lmg.m_fBlendWeight[0+12]=w.w*dh;	lmg.m_fBlendWeight[1+12]=w.z*dh;	
				lmg.m_fBlendWeight[3+12]=w.x*dh;	lmg.m_fBlendWeight[4+12]=w.y*dh;
			}
			else
			{
				//right side
				Vec4 w;
				ComputeWeight4(w, p, p0a,p0b,p08,p07);
				lmg.m_fBlendWeight[1+ 0]=w.w*uh;	lmg.m_fBlendWeight[2+ 0]=w.z*uh;	
				lmg.m_fBlendWeight[4+ 0]=w.x*uh;	lmg.m_fBlendWeight[5+ 0]=w.y*uh;

				lmg.m_fBlendWeight[1+ 6]=w.w*fw;	lmg.m_fBlendWeight[2+ 6]=w.z*fw;	
				lmg.m_fBlendWeight[4+ 6]=w.x*fw;	lmg.m_fBlendWeight[5+ 6]=w.y*fw;

				lmg.m_fBlendWeight[1+12]=w.w*dh;	lmg.m_fBlendWeight[2+12]=w.z*dh;	
				lmg.m_fBlendWeight[4+12]=w.x*dh;	lmg.m_fBlendWeight[5+12]=w.y*dh;
			}
		}

		SPU_NO_INLINE void ComputeWeight_UDH3(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			f32 uh=0,fw=0,dh=0;
			f32	t = lmg.m_BlendSpace.m_slope;
			if (t>0) { uh=t;	fw=1-t;	}
			else {	fw=1+t;	dh=1-(t+1);	}

			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);

			Vec3 bs09=rGlobalAnimHeader.m_arrBSAnimations[0x09].m_Position;		
			Vec3 bs0a=rGlobalAnimHeader.m_arrBSAnimations[0x0a].m_Position;		
			Vec3 bs0b=rGlobalAnimHeader.m_arrBSAnimations[0x0b].m_Position;		

			Vec3 bs0c=rGlobalAnimHeader.m_arrBSAnimations[0x0c].m_Position;		
			Vec3 bs0d=rGlobalAnimHeader.m_arrBSAnimations[0x0d].m_Position;		
			Vec3 bs0e=rGlobalAnimHeader.m_arrBSAnimations[0x0e].m_Position;		

			Vec3 bs0f=rGlobalAnimHeader.m_arrBSAnimations[0x0f].m_Position;		
			Vec3 bs10=rGlobalAnimHeader.m_arrBSAnimations[0x10].m_Position;		
			Vec3 bs11=rGlobalAnimHeader.m_arrBSAnimations[0x11].m_Position;		

			Vec2 p09=Vec2(bs09.x,bs09.y);		Vec2 p0a=Vec2(bs0a.x,bs0a.y);		Vec2 p0b=Vec2(bs0b.x,bs0b.y);
			Vec2 p0c=Vec2(bs0c.x,bs0c.y);		Vec2 p0d=Vec2(bs0d.x,bs0d.y);		Vec2 p0e=Vec2(bs0e.x,bs0e.y);
			Vec2 p0f=Vec2(bs0f.x,bs0f.y);		Vec2 p10=Vec2(bs10.x,bs10.y);		Vec2 p11=Vec2(bs11.x,bs11.y);

			if (lmg.m_BlendSpace.m_speed > 0)
			{
				//fast version
				if (lmg.m_BlendSpace.m_turn<0)
				{
					//left side
					Vec4 w;
					ComputeWeight4(w,p, p0c,p0d,p0a,p09);
					lmg.m_fBlendWeight[0+ 0]=w.w*uh;	lmg.m_fBlendWeight[1+ 0]=w.z*uh;	
					lmg.m_fBlendWeight[3+ 0]=w.x*uh;	lmg.m_fBlendWeight[4+ 0]=w.y*uh;

					lmg.m_fBlendWeight[0+ 9]=w.w*fw;	lmg.m_fBlendWeight[1+ 9]=w.z*fw;	
					lmg.m_fBlendWeight[3+ 9]=w.x*fw;	lmg.m_fBlendWeight[4+ 9]=w.y*fw;

					lmg.m_fBlendWeight[0+18]=w.w*dh;	lmg.m_fBlendWeight[1+18]=w.z*dh;	
					lmg.m_fBlendWeight[3+18]=w.x*dh;	lmg.m_fBlendWeight[4+18]=w.y*dh;
				}
				else
				{
					//right side
					Vec4 w;
					ComputeWeight4(w,p, p0d,p0e,p0b,p0a);
					lmg.m_fBlendWeight[1+ 0]=w.w*uh;	lmg.m_fBlendWeight[2+ 0]=w.z*uh;	
					lmg.m_fBlendWeight[4+ 0]=w.x*uh;	lmg.m_fBlendWeight[5+ 0]=w.y*uh;

					lmg.m_fBlendWeight[1+ 9]=w.w*fw;	lmg.m_fBlendWeight[2+ 9]=w.z*fw;	
					lmg.m_fBlendWeight[4+ 9]=w.x*fw;	lmg.m_fBlendWeight[5+ 9]=w.y*fw;

					lmg.m_fBlendWeight[1+18]=w.w*dh;	lmg.m_fBlendWeight[2+18]=w.z*dh;	
					lmg.m_fBlendWeight[4+18]=w.x*dh;	lmg.m_fBlendWeight[5+18]=w.y*dh;
				}
			}
			else
			{
				//slow version
				if (lmg.m_BlendSpace.m_turn<0)
				{
					//left side
					Vec4 w;
					ComputeWeight4(w,p, p0f,p10,p0d,p0c);
					lmg.m_fBlendWeight[3+ 0]=w.w*uh;	lmg.m_fBlendWeight[4+ 0]=w.z*uh;	
					lmg.m_fBlendWeight[6+ 0]=w.x*uh;	lmg.m_fBlendWeight[7+ 0]=w.y*uh;

					lmg.m_fBlendWeight[3+ 9]=w.w*fw;	lmg.m_fBlendWeight[4+ 9]=w.z*fw;	
					lmg.m_fBlendWeight[6+ 9]=w.x*fw;	lmg.m_fBlendWeight[7+ 9]=w.y*fw;

					lmg.m_fBlendWeight[3+18]=w.w*dh;	lmg.m_fBlendWeight[4+18]=w.z*dh;	
					lmg.m_fBlendWeight[6+18]=w.x*dh;	lmg.m_fBlendWeight[7+18]=w.y*dh;
				}
				else
				{
					//right side
					Vec4 w;
					ComputeWeight4(w, p, p10,p11,p0e,p0d);
					lmg.m_fBlendWeight[4+ 0]=w.w*uh;	lmg.m_fBlendWeight[5+ 0]=w.z*uh;	
					lmg.m_fBlendWeight[7+ 0]=w.x*uh;	lmg.m_fBlendWeight[8+ 0]=w.y*uh;

					lmg.m_fBlendWeight[4+ 9]=w.w*fw;	lmg.m_fBlendWeight[5+ 9]=w.z*fw;	
					lmg.m_fBlendWeight[7+ 9]=w.x*fw;	lmg.m_fBlendWeight[8+ 9]=w.y*fw;

					lmg.m_fBlendWeight[4+18]=w.w*dh;	lmg.m_fBlendWeight[5+18]=w.z*dh;	
					lmg.m_fBlendWeight[7+18]=w.x*dh;	lmg.m_fBlendWeight[8+18]=w.y*dh;
				}
			}
		}

		void ComputeWeight_PUSH(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			float s;
			float t;
			if (!pAnimationSet->m_CharEditMode)
			{
				s = GetParamScale(lmg);
				t = lmg.m_params[eMotionParamID_TurnAngle].blendspace.m_fAssetBlend ;
			}
			else
			{
				s = 0.9f + (lmg.m_BlendSpace.m_speed * 0.5f + 0.5f) * 0.2f;
				s = clamp(s, 0.9f, 1.1f);
				t = lmg.m_BlendSpace.m_turn;
			}

			for (int i = 0; i < 9; i++)
				lmg.m_fBlendWeight[i] = 0.0f;

			int idx0, idx1, idx2, idx3;
			float tl, tr, sb, st;

			if (t < 0)
			{
				tl = -1.0f; tr = 0.0f;

				if (s >= 1.0f)
				{
					sb = 1.0f; st = 1.1f;
					idx0 = 1; idx1 = 4; idx2 = 5; idx3 = 2;
				}
				else
				{
					sb = 0.9f; st = 1.0f;
					idx0 = 0; idx1 = 3; idx2 = 4; idx3 = 1;
				}
			}
			else
			{
				tl = 0.0f; tr = 1.0f;

				if (s >= 1.0f)
				{
					sb = 1.0f; st = 1.1f;
					idx0 = 4; idx1 = 7; idx2 = 8; idx3 = 5;
				}
				else
				{
					sb = 0.9f; st = 1.0f;
					idx0 = 3; idx1 = 6; idx2 = 7; idx3 = 4;
				}
			}

			const float areaInv = 1.0f / ((tr - tl) * (st - sb));
			const float t1 = t - tl;
			const float t2 = tr - t;
			const float s1 = s - sb;
			const float s2 = st - s;
			lmg.m_fBlendWeight[idx0] = t2 * s2 * areaInv;
			lmg.m_fBlendWeight[idx1] = t1 * s2 * areaInv;
			lmg.m_fBlendWeight[idx2] = t1 * s1 * areaInv;
			lmg.m_fBlendWeight[idx3] = t2 * s1 * areaInv;
		}

		void ComputeWeight_PROT(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			// Temporarily disabled for refactoring
			//			m_pSkeletonPose->SetFootAnchoring(0); // Tell motion playback to calculate foot anchoring adjustments.
			//
			f32 t = 0;
			if (!pAnimationSet->m_CharEditMode)
			{
				t = lmg.m_params[eMotionParamID_TurnAngle].blendspace.m_fAssetBlend;
				//t = this->GetDesiredMotionParam(eMotionParamID_TurnAngle);
			}
			else
			{
				t = lmg.m_BlendSpace.m_turn;
			}

			//
			// calc
			//
			if (t<0)
			{
				lmg.m_fBlendWeight[1]=1+t;	//middle
				lmg.m_fBlendWeight[2]=-t;	//left
			}
			else
			{
				lmg.m_fBlendWeight[0]=t;	//right
				lmg.m_fBlendWeight[1]=1-t;	//middle
			}
		}

		void ComputeWeight_SCAL(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			// Temporarily disabled for refactoring
			//			m_pSkeletonPose->SetFootAnchoring(0); // Tell motion playback to not calculate foot anchoring adjustments.
			f32 scale;
			if (!pAnimationSet->m_CharEditMode)
			{
				scale = GetParamScale(lmg);
			}
			else
			{
				scale  = lmg.m_params[eMotionParamID_Scale].blendspace.m_fAssetBlend;
			}

			uint32 numAssets = rGlobalAnimHeader.m_arrBSAnimations.size();
			int idx = -1;
			f32 minDelta = FLT_MAX;
			for (uint32 i = 0; i < numAssets; i++)
			{
				float curScale = rGlobalAnimHeader.m_arrBSAnimations[i].m_Position.y;
				float curDelta = fabs(curScale - scale);
				if (curDelta < minDelta)
				{
					minDelta = curDelta;
					idx = i;
				}
			}
			assert(idx >= 0);

			f32 frontLerp = -1.0f;
			f32 scale0 = rGlobalAnimHeader.m_arrBSAnimations[idx].m_Position.y;
			f32 scale1;

			if (scale < scale0)
			{
				if (idx > 0)
				{
					--idx;
					scale1 = scale0;
					scale0 = rGlobalAnimHeader.m_arrBSAnimations[idx].m_Position.y;
				}
				else
				{
					frontLerp = 1.0f;
				}
			}
			else
			{
				if (idx < (int)numAssets - 1)
				{
					scale1 = rGlobalAnimHeader.m_arrBSAnimations[idx + 1].m_Position.y;
				}
				else
				{
					--idx;
					frontLerp = 0.0f;
				}
			}

			if (frontLerp == -1.0f)
			{
				frontLerp = (scale1 - scale) / (scale1 - scale0);
				frontLerp = clamp(frontLerp, 0.0f, 1.0f);
			}

			lmg.m_fBlendWeight[idx+0] = frontLerp;
			lmg.m_fBlendWeight[idx+1] = 1.0f - frontLerp;
		}

		void ComputeWeight_CLMB(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const float minH = 1.0f;
			const float midH = 1.3f;
			const float maxH = 2.2f;
			const float minS = 0.833f;
			const float midS = 1.0f;
			const float maxS = 1.25f;

			float s = GetParamScale(lmg);
			float h = lmg.m_params[eMotionParamID_Height].blendspace.m_fAssetBlend;
			s = CLAMP(s, minS, maxS);
			h = CLAMP(h, minH, maxH);

			int idx0, idx1, idx2, idx3;
			float hl, hr, sb, st;

			if (h >= midH)
			{
				hl = midH; hr = maxH;
				if (s >= midS)
				{
					idx0 = 7; idx1 = 10; idx2 = 11; idx3 = 8;
					sb = midS; st = maxS;
				}
				else
				{
					idx0 = 6; idx1 = 9; idx2 = 10; idx3 = 7;
					sb = minS; st = midS;
				}
			}
			else
			{
				hl = minH; hr = midH;
				if (s >= midS)
				{
					idx0 = 1; idx1 = 4; idx2 = 5; idx3 = 2;
					sb = midS; st = maxS;
				}
				else
				{
					idx0 = 0; idx1 = 3; idx2 = 4; idx3 = 1;
					sb = minS; st = midS;
				}
			}

			for (int i = 0; i < 12; i++)
				lmg.m_fBlendWeight[i] = 0.0f;

			const float areaInv = 1.0f / ((hr - hl) * (st - sb));
			const float h1 = h - hl;
			const float h2 = hr - h;
			const float s1 = s - sb;
			const float s2 = st - s;
			lmg.m_fBlendWeight[idx0] = h2 * s2 * areaInv;
			lmg.m_fBlendWeight[idx1] = h1 * s2 * areaInv;
			lmg.m_fBlendWeight[idx2] = h1 * s1 * areaInv;
			lmg.m_fBlendWeight[idx3] = h2 * s1 * areaInv;
		}

		void ComputeWeight_COOP(SParametric & lmg, const CAnimationSet * pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{
			const float minH = 2.2f;
			const float midH = 3.0f;
			const float maxH = 3.8f;
			const float minS = 0.9f;
			const float midS = 1.0f;
			const float maxS = 1.1f;

			float s = GetParamScale(lmg);
			float h = lmg.m_params[eMotionParamID_Height].blendspace.m_fAssetBlend;
			s = CLAMP(s, minS, maxS);
			h = CLAMP(h, minH, maxH);

			int idx0, idx1, idx2, idx3;
			float hl, hr, sb, st;

			if (h >= midH)
			{
				hl = midH; hr = maxH;
				if (s >= midS)
				{
					idx0 = 4; idx1 = 7; idx2 = 8; idx3 = 5;
					sb = midS; st = maxS;
				}
				else
				{
					idx0 = 3; idx1 = 6; idx2 = 7; idx3 = 4;
					sb = minS; st = midS;
				}
			}
			else
			{
				hl = minH; hr = midH;
				if (s >= midS)
				{
					idx0 = 1; idx1 = 4; idx2 = 5; idx3 = 2;
					sb = midS; st = maxS;
				}
				else
				{
					idx0 = 0; idx1 = 3; idx2 = 4; idx3 = 1;
					sb = minS; st = midS;
				}
			}

			for (int i = 0; i < 9; i++)
				lmg.m_fBlendWeight[i] = 0.0f;

			const float areaInv = 1.0f / ((hr - hl) * (st - sb));
			const float h1 = h - hl;
			const float h2 = hr - h;
			const float s1 = s - sb;
			const float s2 = st - s;
			lmg.m_fBlendWeight[idx0] = h2 * s2 * areaInv;
			lmg.m_fBlendWeight[idx1] = h1 * s2 * areaInv;
			lmg.m_fBlendWeight[idx2] = h1 * s1 * areaInv;
			lmg.m_fBlendWeight[idx3] = h2 * s1 * areaInv;
		}

		SPU_NO_INLINE void ComputeWeight__TH2(SParametric & lmg, const CAnimationSet* pAnimationSet, GlobalAnimationHeaderCAF * parrGlobalAnimations, GlobalAnimationHeaderLMG& rGHLMG)
		{	
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			f32 uh=0,fw=0,dh=0;
			f32	t = lmg.m_BlendSpace.m_slope;
			if (t>0) { uh=t;	fw=1-t;	}
			else {	fw=1+t;	dh=1-(t+1);	}

			Vec2 p = Vec2(lmg.m_BlendSpace.m_turn,lmg.m_BlendSpace.m_speed);

			Vec3 bs09=rGlobalAnimHeader.m_arrBSAnimations[0x02].m_Position;		
			Vec3 bs0a=rGlobalAnimHeader.m_arrBSAnimations[0x03].m_Position;		
			Vec3 bs0b=rGlobalAnimHeader.m_arrBSAnimations[0x04].m_Position;		
			Vec3 bs0f=rGlobalAnimHeader.m_arrBSAnimations[0x05].m_Position;		
			Vec3 bs10=rGlobalAnimHeader.m_arrBSAnimations[0x06].m_Position;		
			Vec3 bs11=rGlobalAnimHeader.m_arrBSAnimations[0x07].m_Position;		

			Vec2 p09=Vec2(bs09.x,bs09.y);		Vec2 p0a=Vec2(bs0a.x,bs0a.y);		Vec2 p0b=Vec2(bs0b.x,bs0b.y);
			Vec2 p0f=Vec2(bs0f.x,bs0f.y);		Vec2 p10=Vec2(bs10.x,bs10.y);		Vec2 p11=Vec2(bs11.x,bs11.y);

			//fast version
			if (lmg.m_BlendSpace.m_turn<0)
			{
				//left side
				Vec4 w;
				ComputeWeight4(w, p, p0f,p10,p0a,p09);
				lmg.m_fBlendWeight[0]=(w.w+w.z)*uh;	
				lmg.m_fBlendWeight[1]=(w.x+w.y)*uh;	

				lmg.m_fBlendWeight[2]=w.w*fw;	lmg.m_fBlendWeight[3]=w.z*fw;	
				lmg.m_fBlendWeight[5]=w.x*fw;	lmg.m_fBlendWeight[6]=w.y*fw;

				lmg.m_fBlendWeight[8]=(w.w+w.z)*dh;	
				lmg.m_fBlendWeight[9]=(w.x+w.y)*dh;	
			}
			else
			{
				//right side
				Vec4 w;
				ComputeWeight4(w,p, p10,p11,p0b,p0a);
				lmg.m_fBlendWeight[0]=(w.w+w.z)*uh;	
				lmg.m_fBlendWeight[1]=(w.x+w.y)*uh;	

				lmg.m_fBlendWeight[3]=w.w*fw;	lmg.m_fBlendWeight[4]=w.z*fw;	
				lmg.m_fBlendWeight[6]=w.x*fw;	lmg.m_fBlendWeight[7]=w.y*fw;

				lmg.m_fBlendWeight[8]=(w.w+w.z)*dh;	
				lmg.m_fBlendWeight[9]=(w.x+w.y)*dh;	
			}

			f32 fw_fast = lmg.m_fBlendWeight[3];
			f32 fw_slow = lmg.m_fBlendWeight[6];
			if (lmg.m_BlendSpace.m_weightshift>0)
			{
				//weight shift to the right
				lmg.m_fBlendWeight[ 3] = fw_fast*(1.0f-lmg.m_BlendSpace.m_weightshift); //fast
				lmg.m_fBlendWeight[11] = fw_fast*(lmg.m_BlendSpace.m_weightshift);      //fast

				lmg.m_fBlendWeight[ 6] = fw_slow*(1.0f-lmg.m_BlendSpace.m_weightshift); //slow
				lmg.m_fBlendWeight[13] = fw_slow*(lmg.m_BlendSpace.m_weightshift);      //slow
			}
			else
			{
				//weight shift to the left
				lmg.m_fBlendWeight[ 3] = fw_fast*(1.0f-(-lmg.m_BlendSpace.m_weightshift));	//fast
				lmg.m_fBlendWeight[10] = fw_fast*(-lmg.m_BlendSpace.m_weightshift);					//fast

				lmg.m_fBlendWeight[ 6] = fw_slow*(1.0f-(-lmg.m_BlendSpace.m_weightshift));	//slow
				lmg.m_fBlendWeight[12] = fw_slow*(-lmg.m_BlendSpace.m_weightshift);					//slow
			}

#ifdef _DEBUG
			f32 fTotal=0.0f;
			for (uint32 i=0; i<14; i++)
				fTotal+=lmg.m_fBlendWeight[i];
			fTotal = fabsf(fTotal-1.0f);
			assert(fTotal<0.05f);
#endif
		}



		struct BC4 { f32 w0,w1,w2,w3;	};
		struct BC5 { f32 w0,w1,w2,w3,w4; };
		struct BC6 { f32 w0,w1,w2,w3,w4,w5;	};
		struct BC8 { f32 w0,w1,w2,w3,w4,w5,w6,w7;	};

		struct ParaWeight
		{
			Vec4 m_Parameter;
			f32 m_fWeight;
			ParaWeight()
			{
				m_Parameter =Vec4(0,0,0,0); //limited to 4 dimensions
				m_fWeight   =0.0f;
			};
		};

		struct SubBlendSpace
		{
			SubBlendSpace()
			{
				m_nDimensions     = 0;
				m_nExamples       = 0;
			}
			uint32 m_nDimensions;
			uint32 m_nExamples;
			ParaWeight m_arrBlendSpace[80]; //asset and parameter 
		};


		//-----------------------------------------------------------------------------------------------------------
		//-----------------------------------------------------------------------------------------------------------
		//-----------------------------------------------------------------------------------------------------------

		void ConvexPointCloud(const Vec3& cp, SubBlendSpace& rSBS)
		{
			uint32 numAssets = rSBS.m_nExamples;	
			uint32 D = rSBS.m_nDimensions+1; 
			f32 Transpose[MAX_LMG_DIMENSIONS*MAX_LMG_ANIMS];
			f32 pA[MAX_LMG_DIMENSIONS*MAX_LMG_ANIMS];
			f32 pR[MAX_LMG_ANIMS*MAX_LMG_ANIMS];
			f32 pScale[MAX_LMG_ANIMS];
			f32 pWeights[MAX_LMG_ANIMS];

			for(uint32 d=0; d<rSBS.m_nDimensions; ++d)
			{
				for(uint32 a=0; a<numAssets; a++)
					Transpose[a*D+d]=rSBS.m_arrBlendSpace[a].m_Parameter[d]-cp[d];
			}
			for(uint32 a=0; a<numAssets; a++) Transpose[a*D+rSBS.m_nDimensions]=1; //we need homogeneous coordinates

			CSDI ami(numAssets, D, &Transpose[0], &pA[0], &pR[0], &pScale[0]);
			ami.ConstructSDI();
			f32 pParam2[MAX_LMG_DIMENSIONS]; fMatrix param(1, D, &pParam2[0]);
			for(uint32 d=0; d<rSBS.m_nDimensions; d++)
				param(0, d) = 0;
			param( 0, D-1) = 1.0f;
			ami.GetWeights(param.GetData(), &pWeights[0]);

			f32 sumWeights = 0.0f;
			for(uint32 i=0; i<numAssets; ++i)
				sumWeights += pWeights[i];
			for(uint32 i=0; i<numAssets; ++i)
				rSBS.m_arrBlendSpace[i].m_fWeight = pWeights[i]/sumWeights;
		}


		//---------------------------------------------------------------------------------------------
		//---------------------------------------------------------------------------------------------
		//---------------------------------------------------------------------------------------------

		void GetWeights1D( f32 fDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], uint32 print)
		{
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 i=0; i<numExamples; i++) 
				arrWeights[i]=0.0f;

			uint32 InsideFace=-1;
			uint32 numLines=rLMG.m_arrBSAnnotations1.size(); 
			for (uint32 f=0; f<numLines; f++)
			{
				if (rLMG.m_arrBSAnnotations1[f].num==2)
				{
					int32 i0=rLMG.m_arrBSAnnotations1[f].idx0;
					int32 i1=rLMG.m_arrBSAnnotations1[f].idx1;
					f32 x0=rLMG.m_arrParameter[i0].m_Para.x;
					f32 x1=rLMG.m_arrParameter[i1].m_Para.x;
					if ((fDesiredParameter>=x0 && fDesiredParameter<=x1) || (fDesiredParameter>=x1 && fDesiredParameter<=x0))
					{
						g_pAuxGeom->DrawLine(Vec3(x0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), Vec3(x1,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), 1.0f); 
						f32 fDistance  = fabsf(x1-x0); assert(fDistance);
						f32 d = fabsf(fDesiredParameter-x0);
						f32 w0=1.0f-d/fDistance;
						f32 w1=d/fDistance;
						uint32 ex00    =rLMG.m_arrParameter[i0].i0;
						arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*w0;
						uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
						arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*w0;
						uint32 ex10    =rLMG.m_arrParameter[i1].i0;
						arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*w1;
						uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
						arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*w1;
						break;
					}
				}
			} //loop over lines
			assert(InsideFace);
		}



		BC4 GetConvex4(  uint32 numPoints, const Vec2& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], uint8* idx,Vec3* vtx, f32 xmove )
		{
			float fCol1111[4] = {1,1,1,1};
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 e=0; e<numExamples; e++) 
				arrWeights[e]=0.0f;

			uint32 numParameter=rLMG.m_arrParameter.size(); 
			ColorB col[256];
			Vec3 examples[256];
			for (uint32 p=0; p<numParameter; p++)
			{
				if (p<numExamples)
					col[p]=RGBA8(0x00,0x3f,0x00,0x00);
				else
					col[p]=RGBA8(0x3f,0x00,0x00,0x00);
			}

			BC4 bw4;
			bw4.w0=9999.0f;
			bw4.w1=9999.0f;
			bw4.w2=9999.0f;
			bw4.w3=9999.0f;

			if (numPoints==3)
			{
				//Triangle
				uint8 i0=idx[0];	Vec3 v0=vtx[0];
				uint8 i1=idx[1];	Vec3 v1=vtx[1];
				uint8 i2=idx[2];	Vec3 v2=vtx[2];

				//calculate the three weight-values using barycentric coordinates
				f32 px	=	vDesiredParameter.x-v2.x;
				f32 py	=	vDesiredParameter.y-v2.y;
				Vec3 z0	=	v0-v2; 
				Vec3 z1	=	v1-v2; 
				f32 u		= px * z1.y - py * z1.x;
				f32 v		= py * z0.x - px * z0.y;
				f32 w		= z0.x*z1.y - z1.x*z0.y - u-v;
				Vec3 bw = Vec3(u,v,w) / (u+v+w); 

				bw4.w0=bw.x;
				bw4.w1=bw.y;
				bw4.w2=bw.z;
				bw4.w3=0;

				f32 wsum = bw4.w0+bw4.w1+bw4.w2+bw4.w3;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw4.w0;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw4.w0;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw4.w1;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw4.w1;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw4.w2;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw4.w2;

				bool r0 = (bw4.w0>=0.0f && bw4.w0<=1.0f);
				bool r1 = (bw4.w1>=0.0f && bw4.w1<=1.0f);
				bool r2 = (bw4.w2>=0.0f && bw4.w2<=1.0f);
				if (r0 && r1 && r2 && Console::GetInst().ca_DrawVEGInfo)
				{
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
				}
			}

			if (numPoints==4)
			{
				//quad
				uint8 i0=idx[0];	Vec3 v0 = vtx[0];
				uint8 i1=idx[1];	Vec3 v1 = vtx[1];
				uint8 i2=idx[2];	Vec3 v2 = vtx[2];
				uint8 i3=idx[3];	Vec3 v3 = vtx[3];

				Vec4 bw=Vec4(0,0,0,0);
				ComputeWeightExtrapolate4( bw, vDesiredParameter, Vec2(v0),Vec2(v1),Vec2(v2),Vec2(v3) ); 

				bw4.w0=bw.x;
				bw4.w1=bw.y;
				bw4.w2=bw.z;
				bw4.w3=bw.w;

				f32 wsum = bw4.w0+bw4.w1+bw4.w2+bw4.w3;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw4.w0;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw4.w0;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw4.w1;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw4.w1;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw4.w2;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw4.w2;

				uint32 ex30    =rLMG.m_arrParameter[i3].i0;
				arrWeights[ex30] +=rLMG.m_arrParameter[i3].w0*bw4.w3;
				uint32 ex31		 =rLMG.m_arrParameter[i3].i1;
				arrWeights[ex31] +=rLMG.m_arrParameter[i3].w1*bw4.w3;

				bool r0 = (bw4.w0>=0.0f && bw4.w0<=1.0f);
				bool r1 = (bw4.w1>=0.0f && bw4.w1<=1.0f);
				bool r2 = (bw4.w2>=0.0f && bw4.w2<=1.0f);
				bool r3 = (bw4.w3>=0.0f && bw4.w3<=1.0f);
				if (r0 && r1 && r2 && r3 && Console::GetInst().ca_DrawVEGInfo)
				{
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
				}
			}

			return bw4;
		}




		void GetWeights2D( const Vec2& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], f32 xmove)
		{
			float fCol1111[4] = {1,1,1,1};
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 i=0; i<numExamples; i++) 
				arrWeights[i]=0.0f;

			uint8 i[4];	Vec3 v[4];
			uint32 InsideHull=0;
			uint32 numBlocks=rLMG.m_arrBSAnnotations1.size(); 
			for (f32 d=0.0f; d<2.35f; d=d+0.05f)
			{
				for (uint32 b=0; b<numBlocks; b++)
				{
					uint32 numPoints = rLMG.m_arrBSAnnotations1[b].num;
					const uint8* indices = &rLMG.m_arrBSAnnotations1[b].idx0;
					for (uint32 e=0; e<numPoints; e++)
					{
						i[e]=indices[e];
						v[e]=Vec3(rLMG.m_arrParameter[i[e]].m_Para.x,rLMG.m_arrParameter[i[e]].m_Para.y,rLMG.m_arrParameter[i[e]].m_Para.z);
					}

					InsideHull=0;
					BC4 bw = GetConvex4(numPoints,vDesiredParameter,rLMG,arrWeights,i,v,xmove );
					InsideHull=1;
					f32* pbw=&bw.w0;
					for (uint32 e=0; e<numPoints; e++)
					{
						if (pbw[e]<(0.0f-d))
							InsideHull=0;
						if (pbw[e]>(1.0f+d))
							InsideHull=0;
					}

					if (InsideHull) 
					{
						if (Console::GetInst().ca_DrawVEGInfo)
						{
							g_pIRenderer->Draw2dLabel( 1,g_YLine, 4.0f, fCol1111, false,"Inside face: %d",b );	
							g_YLine+=40.0f;
						} 
						return;
					}
				}
			}
		}

		void GetWeights2DKNN( const Vec2& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], uint32 print)
		{
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 i=0; i<numExamples; i++) 
				arrWeights[i]=0.0f;

			uint32 numParameter=rLMG.m_arrParameter.size(); 
			ColorB col[0x100];
			Vec2 examples[0x100];
			for (uint32 p=0; p<numParameter; p++)
			{
				if (p<numExamples)
					col[p]=RGBA8(0x00,0x3f,0x00,0x00);
				else
					col[p]=RGBA8(0x3f,0x00,0x00,0x00);
			}
			for (uint32 i=0; i<min(numExamples,uint32(0xff)); i++)
				examples[i]=Vec2(rLMG.m_arrParameter[i].m_Para.x,rLMG.m_arrParameter[i].m_Para.y);

			uint8 i[4];	Vec3 v[4];
			for (int8 a=0; a<4; a++)
			{
				i[a]=-1;
				v[a]=Vec3(9999.0f,9999.0f,9999.0f);

				for (uint32 e=0; e<numExamples; e++)
				{ 
					f32 fDistance0 = (vDesiredParameter-v[a])   * (vDesiredParameter-v[a]);
					f32 fDistance1 = (vDesiredParameter-examples[e]) * (vDesiredParameter-examples[e]);
					if (fDistance0>fDistance1)
						v[a]=examples[e],i[a]=e;
				}
				examples[i[a]]=Vec2(99990.0f,99990.0f);
			}



			uint8 i0=i[0];	Vec3 v0 = v[0];
			uint8 i1=i[1];	Vec3 v1 = v[1];
			uint8 i2=i[2];	Vec3 v2 = v[2];
			uint8 i3=i[3];	Vec3 v3 = v[3];
			g_pAuxGeom->DrawTriangle( v0-Vec3(0,0,0.02f),col[i0], v1-Vec3(0,0,0.02f),col[i1], v2,col[i2]); 
			g_pAuxGeom->DrawTriangle( v0-Vec3(0,0,0.02f),col[i0], v2-Vec3(0,0,0.02f),col[i2], v3,col[i3]); 
			g_pAuxGeom->DrawLine(v0+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
			g_pAuxGeom->DrawLine(v1+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
			g_pAuxGeom->DrawLine(v2+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
			g_pAuxGeom->DrawLine(v3+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(0,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 

			{
				g_pAuxGeom->DrawLine(v0+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), v1+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), 1.0f); 
				g_pAuxGeom->DrawLine(v1+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), v2+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), 1.0f); 
				g_pAuxGeom->DrawLine(v2+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), v3+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), 1.0f); 
				g_pAuxGeom->DrawLine(v3+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), v0+Vec3(0,0,0.04f),RGBA8(0xff,0xff,0xff,0x00), 1.0f); 

				Vec3 cp=Vec2(vDesiredParameter);
				SubBlendSpace bspace;
				bspace.m_nDimensions=2;
				bspace.m_nExamples=4;
				bspace.m_arrBlendSpace[0].m_Parameter = Vec4(v0.x,v0.y,1,0);
				bspace.m_arrBlendSpace[1].m_Parameter = Vec4(v1.x,v1.y,1,0);
				bspace.m_arrBlendSpace[2].m_Parameter = Vec4(v2.x,v2.y,1,0);
				bspace.m_arrBlendSpace[3].m_Parameter = Vec4(v3.x,v3.y,1,0);
				ConvexPointCloud(cp,bspace);
				Vec4 bw;
				bw.x=bspace.m_arrBlendSpace[0].m_fWeight;
				bw.y=bspace.m_arrBlendSpace[1].m_fWeight;
				bw.z=bspace.m_arrBlendSpace[2].m_fWeight;
				bw.w=bspace.m_arrBlendSpace[3].m_fWeight;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw.x;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw.x;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw.y;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw.y;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw.z;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw.z;

				uint32 ex30    =rLMG.m_arrParameter[i3].i0;
				arrWeights[ex30] +=rLMG.m_arrParameter[i3].w0*bw.w;
				uint32 ex31		 =rLMG.m_arrParameter[i3].i1;
				arrWeights[ex31] +=rLMG.m_arrParameter[i3].w1*bw.w;
				//break;
			}
		}



		BC4 WeightTetrahedron( const Vec3& CP, const Vec3 &t0, const Vec3 &t1, const Vec3 &t2, const Vec3 &t3 ) 
		{
			BC4 bc;
			Vec3 n = (t3-t0)%(t2-t0);
			f32 m  = n*(t1-t0);
			bc.w0 = (((t2-t1)%(t3-t1))|(CP-t0))/m+1;
			bc.w1 = (((t0-t2)%(t3-t2))|(CP-t1))/m+1;
			bc.w2 = (((t0-t3)%(t1-t3))|(CP-t2))/m+1;
			bc.w3 = (((t2-t0)%(t1-t0))|(CP-t3))/m+1;
			f32 sum=bc.w0+bc.w1+bc.w2+bc.w3;
			assert(fabsf(sum-1.0f)<0.0001f);
			return bc;
		}

		BC5 WeightPyramid(const Vec3& ControlPoint, const Vec3& t0,const Vec3& t1,const Vec3& t2,const Vec3& t3,const Vec3& t4 )
		{
			f32 w[5];		w[0]=0.0f; w[1]=0.0f; w[2]=0.0f;	w[3]=0.0f;	w[4]=0.0f;
			Vec3 t[5]; 	t[0]=t0;	 t[1]=t1;		t[2]=t2;		t[3]=t3;		t[4]=t4;
			for (uint32 e=0; e<4; e++)
			{
				int32 i0=(e+0)&3;
				int32 i1=(e+1)&3;
				int32 i2=(e+2)&3;
				int32 i3=4;
				BC4 bc = WeightTetrahedron( ControlPoint, t[i0],t[i1],t[i2],t[i3]);
				if (bc.w1>=0)
					w[i0]+=bc.w0,w[i1]+=bc.w1,w[i2]+=bc.w2,w[i3]+=bc.w3;
			}

			f32 sum=w[0]+w[1]+w[2]+w[3] + w[4];
			if (sum)
				w[0]/=sum,w[1]/=sum,w[2]/=sum,w[3]/=sum,w[4]/=sum;

			BC5 bc5; bc5.w0=w[0]; bc5.w1=w[1]; bc5.w2=w[2]; bc5.w3=w[3]; bc5.w4=w[4];
			return bc5;
		}

		BC6 WeightPrism(const Vec3& ControlPoint, const Vec3& t0,const Vec3& t1,const Vec3& t2,const Vec3& t3,const Vec3& t4,const Vec3& t5 )
		{
			f32 w[6];	w[0]=0.0f; w[1]=0.0f;	w[2]=0.0f;	w[3]=0.0f;	w[4]=0.0f;	w[5]=0.0f;

			Vec3 t[6]; t[0]=t0;	t[1]=t1; t[2]=t2;	t[3]=t3;	t[4]=t4; t[5]=t5;

			int32 i0=0;
			int32 i1=1;
			int32 i2=2;
			int32 i3=3;
			int32 i4=5;
			Plane plane2 = Plane::CreatePlane( t[i0],t[i1],t[i4] ); 
			if ((plane2|ControlPoint)<=0)
			{
				BC5 bc = WeightPyramid( ControlPoint, t[i0],t[i1],t[i2],t[i3],t[i4]);
				w[i0]+=bc.w0; w[i1]+=bc.w1; w[i2]+=bc.w2; w[i3]+=bc.w3; w[i4]+=bc.w4;
			}

			i0=0;
			i1=1;
			i2=5;
			i3=4;
			Plane plane3 = Plane::CreatePlane( t[i1],t[i0],t[i2] ); 
			if ((plane3|ControlPoint)<=0)
			{
				BC4 bc = WeightTetrahedron( ControlPoint, t[i0],t[i1],t[i2],t[i3] );
				w[i0]+=bc.w0; w[i1]+=bc.w1; w[i2]+=bc.w2; w[i3]+=bc.w3;
			}

			f32 sum=w[0]+w[1]+w[2]+w[3] + w[4]+w[5];
			if (sum)
				w[0]/=sum,w[1]/=sum,w[2]/=sum,w[3]/=sum,w[4]/=sum,w[5]/=sum;

			BC6 bc6; bc6.w0=w[0]; bc6.w1=w[1]; bc6.w2=w[2]; bc6.w3=w[3]; bc6.w4=w[4]; bc6.w5=w[5];
			return bc6;
		}





		BC8 GetConvex8(  uint32 numPoints, const Vec3& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], uint8* i,Vec3* v, f32 xmove )
		{
			float fCol1111[4] = {1,1,1,1};
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 e=0; e<numExamples; e++) 
				arrWeights[e]=0.0f;

			uint32 numParameter=rLMG.m_arrParameter.size(); 
			ColorB col[0xff];
			Vec3 examples[0xff];
			for (uint32 p=0; p<numParameter; p++)
			{
				if (p<numExamples)
					col[p]=RGBA8(0x00,0x3f,0x00,0x00);
				else
					col[p]=RGBA8(0x3f,0x00,0x00,0x00);
			}

			BC8 bw;
			bw.w0=9999.0f;
			bw.w1=9999.0f;
			bw.w2=9999.0f;
			bw.w3=9999.0f;
			bw.w4=9999.0f;
			bw.w5=9999.0f;
			bw.w6=9999.0f;
			bw.w7=9999.0f;

			if (numPoints==4)
			{
				//Tetrahedron
				uint8 i0=i[0];	Vec3 v0=v[0];
				uint8 i1=i[1];	Vec3 v1=v[1];
				uint8 i2=i[2];	Vec3 v2=v[2];
				uint8 i3=i[3];	Vec3 v3=v[3];

				uint32 pl0 = fabsf(v0.z)<0.01f; 
				uint32 pl1 = fabsf(v1.z)<0.01f; 
				uint32 pl2 = fabsf(v2.z)<0.01f; 
				uint32 pl3 = fabsf(v3.z)<0.01f; 
				if (pl0 && pl1 && pl2 && pl3)
					return bw;

				BC4 bw4 = WeightTetrahedron( vDesiredParameter, v0,v1,v2,v3 ); 

				bw.w0=bw4.w0;
				bw.w1=bw4.w1;
				bw.w2=bw4.w2;
				bw.w3=bw4.w3;
				bw.w4=0;
				bw.w5=0;
				bw.w6=0;
				bw.w7=0;
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"3d-tetrahedron: %f %f %f %f",bw.w0,bw.w1,bw.w2,bw.w3 );	
				//	g_YLine+=20.0f;

				f32 wsum = bw.w0+bw.w1+bw.w2+bw.w3 + bw.w4+bw.w5+bw.w6+bw.w7;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw.w0;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw.w0;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw.w1;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw.w1;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw.w2;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw.w2;

				uint32 ex30    =rLMG.m_arrParameter[i3].i0;
				arrWeights[ex30] +=rLMG.m_arrParameter[i3].w0*bw.w3;
				uint32 ex31		 =rLMG.m_arrParameter[i3].i1;
				arrWeights[ex31] +=rLMG.m_arrParameter[i3].w1*bw.w3;

				bool r0 = (bw4.w0>=0.0f && bw4.w0<=1.0f);
				bool r1 = (bw4.w1>=0.0f && bw4.w1<=1.0f);
				bool r2 = (bw4.w2>=0.0f && bw4.w2<=1.0f);
				bool r3 = (bw4.w3>=0.0f && bw4.w3<=1.0f);
				if (r0 && r1 && r2 && r3 && Console::GetInst().ca_DrawVEGInfo)
				{
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
				}
			}

			if (numPoints==5)
			{
				//Pyramid
				uint8 i0=i[0];	Vec3 v0 = v[0];
				uint8 i1=i[1];	Vec3 v1 = v[1];
				uint8 i2=i[2];	Vec3 v2 = v[2];
				uint8 i3=i[3];	Vec3 v3 = v[3];
				uint8 i4=i[4];	Vec3 v4 = v[4];

				uint32 pl0 = fabsf(v0.z)<0.01f; 
				uint32 pl1 = fabsf(v1.z)<0.01f; 
				uint32 pl2 = fabsf(v2.z)<0.01f; 
				uint32 pl3 = fabsf(v3.z)<0.01f; 
				uint32 pl4 = fabsf(v4.z)<0.01f; 
				if (pl0 && pl1 && pl2 && pl3 && pl4)
					return bw;

				BC5 bw5 = WeightPyramid( vDesiredParameter, v0,v1,v2,v3,v4 ); 

				bw.w0=bw5.w0;
				bw.w1=bw5.w1;
				bw.w2=bw5.w2;
				bw.w3=bw5.w3;
				bw.w4=bw5.w4;
				bw.w5=0;
				bw.w6=0;
				bw.w7=0;
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"3d-pyramid: %f %f %f %f %f",bw.w0,bw.w1,bw.w2,bw.w3,bw.w4 );	
				//	g_YLine+=20.0f;

				f32 wsum = bw.w0+bw.w1+bw.w2+bw.w3 + bw.w4+bw.w5+bw.w6+bw.w7;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw.w0;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw.w0;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw.w1;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw.w1;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw.w2;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw.w2;

				uint32 ex30    =rLMG.m_arrParameter[i3].i0;
				arrWeights[ex30] +=rLMG.m_arrParameter[i3].w0*bw.w3;
				uint32 ex31		 =rLMG.m_arrParameter[i3].i1;
				arrWeights[ex31] +=rLMG.m_arrParameter[i3].w1*bw.w3;

				uint32 ex40    =rLMG.m_arrParameter[i4].i0;
				arrWeights[ex40] +=rLMG.m_arrParameter[i4].w0*bw.w4;
				uint32 ex41		 =rLMG.m_arrParameter[i4].i1;
				arrWeights[ex41] +=rLMG.m_arrParameter[i4].w1*bw.w4;

				bool r0 = (bw5.w0>=0.0f && bw5.w0<=1.0f);
				bool r1 = (bw5.w1>=0.0f && bw5.w1<=1.0f);
				bool r2 = (bw5.w2>=0.0f && bw5.w2<=1.0f);
				bool r3 = (bw5.w3>=0.0f && bw5.w3<=1.0f);
				bool r4 = (bw5.w4>=0.0f && bw5.w4<=1.0f);
				if (r0 && r1 && r2 && r3 && r4 && Console::GetInst().ca_DrawVEGInfo)
				{
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 

					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
				}
			}

			if (numPoints==6)
			{
				//Pyramid
				uint8 i0=i[0];	Vec3 v0 = v[0];
				uint8 i1=i[1];	Vec3 v1 = v[1];
				uint8 i2=i[2];	Vec3 v2 = v[2];
				uint8 i3=i[3];	Vec3 v3 = v[3];
				uint8 i4=i[4];	Vec3 v4 = v[4];
				uint8 i5=i[5];	Vec3 v5 = v[5];

				uint32 pl0 = fabsf(v0.z)<0.01f; 
				uint32 pl1 = fabsf(v1.z)<0.01f; 
				uint32 pl2 = fabsf(v2.z)<0.01f; 
				uint32 pl3 = fabsf(v3.z)<0.01f; 
				uint32 pl4 = fabsf(v4.z)<0.01f; 
				uint32 pl5 = fabsf(v5.z)<0.01f; 
				if (pl0 && pl1 && pl2 && pl3 && pl4)
					return bw;

				BC6 bw6 = WeightPrism( vDesiredParameter, v0,v1,v2, v3,v4,v5 ); 

				bw.w0=bw6.w0;
				bw.w1=bw6.w1;
				bw.w2=bw6.w2;
				bw.w3=bw6.w3;
				bw.w4=bw6.w4;
				bw.w5=bw6.w5;
				bw.w6=0;
				bw.w7=0;
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"3d-pyramid: %f %f %f %f %f",bw.w0,bw.w1,bw.w2,bw.w3,bw.w4 );	
				//	g_YLine+=20.0f;

				f32 wsum = bw.w0+bw.w1+bw.w2+bw.w3 + bw.w4+bw.w5+bw.w6+bw.w7;

				uint32 ex00    =rLMG.m_arrParameter[i0].i0;
				arrWeights[ex00] +=rLMG.m_arrParameter[i0].w0*bw.w0;
				uint32 ex01		 =rLMG.m_arrParameter[i0].i1;
				arrWeights[ex01] +=rLMG.m_arrParameter[i0].w1*bw.w0;

				uint32 ex10    =rLMG.m_arrParameter[i1].i0;
				arrWeights[ex10] +=rLMG.m_arrParameter[i1].w0*bw.w1;
				uint32 ex11		 =rLMG.m_arrParameter[i1].i1;
				arrWeights[ex11] +=rLMG.m_arrParameter[i1].w1*bw.w1;

				uint32 ex20    =rLMG.m_arrParameter[i2].i0;
				arrWeights[ex20] +=rLMG.m_arrParameter[i2].w0*bw.w2;
				uint32 ex21		 =rLMG.m_arrParameter[i2].i1;
				arrWeights[ex21] +=rLMG.m_arrParameter[i2].w1*bw.w2;

				uint32 ex30    =rLMG.m_arrParameter[i3].i0;
				arrWeights[ex30] +=rLMG.m_arrParameter[i3].w0*bw.w3;
				uint32 ex31		 =rLMG.m_arrParameter[i3].i1;
				arrWeights[ex31] +=rLMG.m_arrParameter[i3].w1*bw.w3;

				uint32 ex40    =rLMG.m_arrParameter[i4].i0;
				arrWeights[ex40] +=rLMG.m_arrParameter[i4].w0*bw.w4;
				uint32 ex41		 =rLMG.m_arrParameter[i4].i1;
				arrWeights[ex41] +=rLMG.m_arrParameter[i4].w1*bw.w4;

				uint32 ex50    =rLMG.m_arrParameter[i5].i0;
				arrWeights[ex50] +=rLMG.m_arrParameter[i5].w0*bw.w5;
				uint32 ex51		 =rLMG.m_arrParameter[i5].i1;
				arrWeights[ex51] +=rLMG.m_arrParameter[i5].w1*bw.w5;

				bool r0 = (bw6.w0>=0.0f && bw6.w0<=1.0f);
				bool r1 = (bw6.w1>=0.0f && bw6.w1<=1.0f);
				bool r2 = (bw6.w2>=0.0f && bw6.w2<=1.0f);
				bool r3 = (bw6.w3>=0.0f && bw6.w3<=1.0f);
				bool r4 = (bw6.w4>=0.0f && bw6.w4<=1.0f);
				bool r5 = (bw6.w5>=0.0f && bw6.w5<=1.0f);
				if (r0 && r1 && r2 && r3 && r4 && r5 && Console::GetInst().ca_DrawVEGInfo)
				{
					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 
					g_pAuxGeom->DrawLine(v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f); 

					g_pAuxGeom->DrawLine(v0+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f);
					g_pAuxGeom->DrawLine(v1+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f);
					g_pAuxGeom->DrawLine(v2+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v5+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f);
					g_pAuxGeom->DrawLine(v3+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v5+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f);

					g_pAuxGeom->DrawLine(v4+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), v5+Vec3(xmove,0,0.02f),RGBA8(0x00,0xff,0x00,0x00), 1.0f);
				}
			}

			return bw;
		}


		void GetWeights3D_1( const Vec3& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], f32 xmove)
		{
			float fCol1111[4] = {1,1,1,1};
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 i=0; i<numExamples; i++) 
				arrWeights[i]=0.0f;

			uint8 i[8];	Vec3 v[8];
			uint32 InsideHull=0;
			uint32 numBlocks=rLMG.m_arrBSAnnotations1.size(); 
			for (f32 d=0.0f; d<2.35f; d=d+0.05f)
			{
				for (uint32 b=0; b<numBlocks; b++)
				{
					uint32 numPoints = rLMG.m_arrBSAnnotations1[b].num;
					const uint8* indices = &rLMG.m_arrBSAnnotations1[b].idx0;
					for (uint32 e=0; e<numPoints; e++)
					{
						i[e]=indices[e];
						v[e]=Vec3(rLMG.m_arrParameter[i[e]].m_Para.x,rLMG.m_arrParameter[i[e]].m_Para.y,rLMG.m_arrParameter[i[e]].m_Para.z);
					}

					InsideHull=0;
					BC8 bw = GetConvex8(numPoints,vDesiredParameter,rLMG,arrWeights,i,v,xmove );
					InsideHull=1;
					f32* pbw=&bw.w0;
					for (uint32 e=0; e<numPoints; e++)
					{
						if (pbw[e]<(0.0f-d))
							InsideHull=0;
						if (pbw[e]>(1.0f+d))
							InsideHull=0;
					}

					if (InsideHull) 
					{
						if (Console::GetInst().ca_DrawVEGInfo)
						{
							g_pIRenderer->Draw2dLabel( 1,g_YLine, 4.0f, fCol1111, false,"Inside Block1: %d",b );	
							g_YLine+=40.0f;
						} 
						return;
					}
				}
			}
		}


		void GetWeights3D_2( const Vec3& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], f32 xmove)
		{
			float fCol1111[4] = {1,1,1,1};
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 i=0; i<numExamples; i++) 
				arrWeights[i]=0.0f;

			uint8 i[8];	Vec3 v[8];
			uint32 InsideHull=0;
			uint32 numBlocks=rLMG.m_arrBSAnnotations2.size(); 
			for (f32 d=0.0f; d<2.35f; d=d+0.05f)
			{
				for (uint32 b=0; b<numBlocks; b++)
				{
					uint32 numPoints = rLMG.m_arrBSAnnotations2[b].num;
					const uint8* indices = &rLMG.m_arrBSAnnotations2[b].idx0;
					for (uint32 e=0; e<numPoints; e++)
					{
						i[e]=indices[e];
						v[e]=Vec3(rLMG.m_arrParameter[i[e]].m_Para.x,rLMG.m_arrParameter[i[e]].m_Para.y,rLMG.m_arrParameter[i[e]].m_Para.w);
					}

					InsideHull=0;
					BC8 bw = GetConvex8(numPoints,vDesiredParameter,rLMG,arrWeights,i,v, xmove );
					InsideHull=1;
					f32* pbw=&bw.w0;
					for (uint32 e=0; e<numPoints; e++)
					{
						if (pbw[e]<(0.0f-d))
							InsideHull=0;
						if (pbw[e]>(1.0f+d))
							InsideHull=0;
					}

					if (InsideHull) 
					{
						if (Console::GetInst().ca_DrawVEGInfo)
						{
							g_pIRenderer->Draw2dLabel( 1,g_YLine, 4.0f, fCol1111, false,"Inside Block1: %d",b );	
							g_YLine+=40.0f;
						} 
						return;
					}
				}
			}
		}


		void GetWeights3DKNN( const Vec3& vDesiredParameter, const GlobalAnimationHeaderLMG& rLMG, f32 arrWeights[], uint32 print)
		{
			float fCol1111[4] = {1,1,1,1};
			uint8 i[8];	Vec3 v[8];
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			for (uint32 e=0; e<numExamples; e++) 
				arrWeights[e]=0.0f;

			uint32 numParameter=rLMG.m_arrParameter.size(); 
			ColorB col[0x100];
			Vec3 examples[0x100];
			for (uint32 p=0; p<numParameter; p++)
			{
				if (p<numExamples)
					col[p]=RGBA8(0x00,0x3f,0x00,0x00);
				else
					col[p]=RGBA8(0x3f,0x00,0x00,0x00);
			}
			for (uint32 c=0; c<min(numExamples,uint32(0xff)); c++)
			{
				examples[c].x=rLMG.m_arrParameter[c].m_Para.x;
				examples[c].y=rLMG.m_arrParameter[c].m_Para.y;
				examples[c].z=rLMG.m_arrParameter[c].m_Para.z;
			}
			for (uint32 a=0; a<8; a++)
			{
				i[a]=-1;
				v[a]=Vec3(9999.0f,9999.0f,9999.0f);

				for (uint32 e=0; e<numExamples; e++)
				{ 
					f32 fDistance0 = (vDesiredParameter-v[a])   * (vDesiredParameter-v[a]);
					f32 fDistance1 = (vDesiredParameter-examples[e]) * (vDesiredParameter-examples[e]);
					if (fDistance0>fDistance1)
						v[a]=examples[e],i[a]=e;
				}
				examples[i[a]]=Vec3(99990.0f,99990.0f,99990.0f);
			}

			for (uint32 e=0; e<8; e++)
			{ 
				//	v[e]=examples[e]; i[e]=e;
				f32 fDistance1 = (vDesiredParameter-v[e]) * (vDesiredParameter-v[e]);
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"Para: %f %f %f   fDistance1: %f",v[e].x,v[e].y,v[e].z, fDistance1 );	
				g_YLine+=20.0f;
			}
			GetConvex8(8,vDesiredParameter,rLMG,arrWeights,i,v,0 );
		}

		void ComputeWeight_PARA1D(SParametric& lmg, GlobalAnimationHeaderLMG& rLMG)
		{
			float fCol1111[4] = {1,1,1,1};
			float fCol1011[4] = {1,0,1,1};
			uint32 nDimensions = rLMG.m_Dimensions;
			uint32 numExamples = rLMG.m_arrBSAnimations.size();
			uint32 numParameter	=	rLMG.m_arrParameter.size(); 

			lmg.m_fBlendWeight[0]=1.0f;

			static Ang3 angles=Ang3(0,0,0);
			angles.x+=0.01f;
			angles.y+=0.02f;
			angles.z+=0.03f;
			Matrix33 _m33=Matrix33::CreateRotationXYZ(angles);
			AABB aabb1 = AABB(Vec3( -0.02f, -0.02f, -0.02f),Vec3( 0.02f, 0.02f, 0.02f));
			OBB _obb1=OBB::CreateOBBfromAABB( _m33,aabb1 );
			AABB aabb2 = AABB(Vec3( -0.05f, -0.05f, -0.05f),Vec3( 0.05f, 0.05f, 0.05f));
			OBB _obb2=OBB::CreateOBBfromAABB( _m33,aabb2 );

			//---------------------------------------------------

			f32 arrWeights[0xff];
			Vec3 vDesiredParameter=Vec3(0,0,0);

			//-------------------------------------------------------------
			//Dimension=1
			uint32 initD1=0;
			if (rLMG.m_strParaName0=="MoveSpeed")
			{
				vDesiredParameter.x= lmg.m_params[eMotionParamID_TravelSpeed].value;
				initD1 = lmg.m_params[eMotionParamID_TravelSpeed].initialized;
			}
			if (rLMG.m_strParaName0=="TurnAngle")
			{
				vDesiredParameter.x= lmg.m_params[eMotionParamID_TurnAngle].value;
				initD1 = lmg.m_params[eMotionParamID_TurnAngle].initialized;
			}
			if (rLMG.m_strParaName0=="TurnSpeed")
			{
				vDesiredParameter.x= lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD1 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			vDesiredParameter.x*=rLMG.m_scale0;
			vDesiredParameter.x=min(rLMG.m_max0,vDesiredParameter.x);
			vDesiredParameter.x=max(rLMG.m_min0,vDesiredParameter.x);



			f32 xmove1=3;
			f32 xstep=(rLMG.m_max0-rLMG.m_min0)/f32(rLMG.m_cells0-1);
			if (Console::GetInst().ca_DrawVEGInfo) 
			{
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName0.c_str(),vDesiredParameter.x/rLMG.m_scale0,initD1 );	
				g_YLine+=20.0f;
				g_pAuxGeom->DrawLine(Vec3(xmove1+rLMG.m_min0,0,0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+rLMG.m_max0,0,0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
				g_pAuxGeom->DrawOBB(_obb2,Vec3(xmove1+vDesiredParameter.x,vDesiredParameter.y,0.05f),1,RGBA8(0x00,0x00,0x00,0x00),eBBD_Extremes_Color_Encoded);
			}

			uint32 initialized=rLMG.m_ParaGrid1D.size();
			if (initialized==0)
			{
				rLMG.m_ParaGrid1D.resize(rLMG.m_cells0);
				uint32 c0=0;
				for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep )
				{
					GetWeights1D( x, rLMG, arrWeights,0);
					rLMG.m_ParaGrid1D[c0].i0=0;	
					rLMG.m_ParaGrid1D[c0].i1=0;	
					rLMG.m_ParaGrid1D[c0].w0=0.0f;	
					rLMG.m_ParaGrid1D[c0].w1=0.0f;	

					uint32 c=0;
					uint8* pI=&(rLMG.m_ParaGrid1D[c0].i0);	
					float* pW=&(rLMG.m_ParaGrid1D[c0].w0);	
					for (uint32 i=0; i<numExamples; i++)
					{
						f32 w=arrWeights[i];
						if (w)
						{
							if (c>1)
								CryFatalError("Invalid Weights");
							pI[c]=i;	
							pW[c]=w;	
							c++;
						}
					}

					f32 sum=0.0f;
					sum += rLMG.m_ParaGrid1D[c0].w0;
					sum += rLMG.m_ParaGrid1D[c0].w1;
					if ( fabsf(sum-1.0f)>0.001f )
					{
						g_pIRenderer->Draw2dLabel( 1,g_YLine, 3.0f, fCol1111, false,"invalid sum: %f",sum );	
						g_YLine+=31.0f;
					}
					c0++;
				}
			}



			//---------------------------------------------------------------------------------------------
			//---                   visualize the virtual-examples                                  -------
			//---------------------------------------------------------------------------------------------
			uint32 numVExamples = rLMG.m_ParaGrid1D.size();
			if (numVExamples)
			{
				if (Console::GetInst().ca_DrawVEGInfo) 
				{
					for (uint32 n=0; n<numVExamples; n++)
					{
						VExample1D ve = rLMG.m_ParaGrid1D[n];
						Vec3 v0=Vec3(rLMG.m_arrParameter[ve.i0].m_Para.x,0,0);
						Vec3 v1=Vec3(rLMG.m_arrParameter[ve.i1].m_Para.x,0,0);
						Vec3 ip = (v0*ve.w0 + v1*ve.w1) +Vec3(xmove1,0,0.05f);  
						g_pAuxGeom->DrawOBB(_obb1,ip,1,RGBA8(0x00,0x00,0x7f,0x00),eBBD_Extremes_Color_Encoded);
					}
				}
				//---------------------------------------------------------------------------------------------
				//---                   this is the 1D-parameterizer     --------------------------------------
				//---------------------------------------------------------------------------------------------
				VExample1D ve;
				f32 cel0=f32(rLMG.m_cells0-1);
				f32 cel1=f32(rLMG.m_cells1-1);
				f32 fx=(vDesiredParameter.x-rLMG.m_min0) / ((rLMG.m_max0-rLMG.m_min0)/cel0);
				fx=clamp(fx,0.0f,cel0-0.001f);
				int32 ix	=	int32(fx);
				f32 px		=	fx-f32(ix);
			//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"dpx:%f  ix:%d  px:%f",vDesiredParameter.x,ix,px);	
			//	g_YLine+=21.0f;
				for (uint32 i=0; i<numExamples; i++)	arrWeights[i]=0;
				ve = rLMG.m_ParaGrid1D[ix];
				arrWeights[ve.i0]+=f32(ve.w0)*(1-px);	
				arrWeights[ve.i1]+=f32(ve.w1)*(1-px);	
				ve = rLMG.m_ParaGrid1D[ix+1];
				arrWeights[ve.i0]+=f32(ve.w0)*px;
				arrWeights[ve.i1]+=f32(ve.w1)*px;

				if (0)
				{
					uint8 arrI[0xff];
					f32 arrW[0xff];
					for (uint32 i=0; i<40; i++)
					{
						arrI[i]=0;
						arrW[i]=0;
					}

					uint32 c=0;
					for (uint32 i=0; i<numExamples; i++)
					{
						if (arrWeights[i])
						{
							arrI[c]=i;	
							arrW[c]=arrWeights[i];	
							c++;
						}
					}
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1011, false,"indices: %d %d %d %d %d %d",arrI[0],arrI[1],arrI[2],arrI[3],arrI[4],arrI[5] );	
					g_YLine+=21.0f;
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1011, false,"weights: %f %f %f %f %f %f",arrW[0],arrW[1],arrW[2],arrW[3],arrW[4],arrW[5] );	
					g_YLine+=21.0f;
				}
			}


			f32 sum=0.0f;
			for (uint32 i=0; i<numExamples; i++) 
				if (fabsf(arrWeights[i])<0.015f)		arrWeights[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
				sum+=arrWeights[i];
			if (sum==0)
				arrWeights[0]=1.0f,sum=1.0f;
			for (uint32 i=0; i<numExamples; i++)
				lmg.m_fBlendWeight[i]=arrWeights[i]/sum;	

#ifdef _DEBUG
			f32 sum2=0.0f;
			for (uint32 i=0; i<numExamples; i++)
				sum2 += lmg.m_fBlendWeight[i];	
			assert( fabsf(sum2-1.0f)<0.05f );
			g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"sum2: %f",sum2);	
			g_YLine+=21.0f;
#endif
		}



		void ComputeWeight_PARA2D(SParametric& lmg, GlobalAnimationHeaderLMG& rLMG)
		{
			float fCol1111[4] = {1,1,1,1};
			float fCol1011[4] = {1,0,1,1};
			uint32 nDimensions = rLMG.m_Dimensions;
			uint32 numExamples = rLMG.m_arrBSAnimations.size();

			static Ang3 angles=Ang3(0,0,0);
			angles.x+=0.01f;
			angles.y+=0.02f;
			angles.z+=0.03f;
			Matrix33 _m33=Matrix33::CreateRotationXYZ(angles);
			AABB aabb1 = AABB(Vec3( -0.02f, -0.02f, -0.02f),Vec3( 0.02f, 0.02f, 0.02f));
			OBB _obb1=OBB::CreateOBBfromAABB( _m33,aabb1 );
			AABB aabb2 = AABB(Vec3( -0.05f, -0.05f, -0.05f),Vec3( 0.05f, 0.05f, 0.05f));
			OBB _obb2=OBB::CreateOBBfromAABB( _m33,aabb2 );


			//---------------------------------------------------

			f32 arrWeights[256];
			Vec2 vDesiredParameter=Vec2(0,0);

			//-------------------------------------------------------------
			//Dimension=1
			uint32 initD1=0;
			if (rLMG.m_strParaName0=="MoveSpeed")
			{
				vDesiredParameter.x = lmg.m_params[eMotionParamID_TravelSpeed].value;
				initD1 = lmg.m_params[eMotionParamID_TravelSpeed].initialized;
			}
			vDesiredParameter.x*=rLMG.m_scale0;
			vDesiredParameter.x=min(rLMG.m_max0,vDesiredParameter.x);
			vDesiredParameter.x=max(rLMG.m_min0,vDesiredParameter.x);

			//-------------------------------------------------------------
			//Dimension=2
			uint32 initD2=0;
			if (rLMG.m_strParaName1=="TurnSpeed")
			{
				vDesiredParameter.y=lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD2 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName1=="TravelAngle")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelAngle].value;
				initD2 = lmg.m_params[eMotionParamID_TravelAngle].initialized;
			}
			if (rLMG.m_strParaName1=="TravelSlope")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD2 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.y*=rLMG.m_scale1;
			vDesiredParameter.y=min(rLMG.m_max1,vDesiredParameter.y);
			vDesiredParameter.y=max(rLMG.m_min1,vDesiredParameter.y);





			f32 xmove1=3;
			f32 xstep=(rLMG.m_max0-rLMG.m_min0)/f32(rLMG.m_cells0-1);
			f32 ystep=(rLMG.m_max1-rLMG.m_min1)/f32(rLMG.m_cells1-1);
			if (Console::GetInst().ca_DrawVEGInfo ) 
			{
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName0.c_str(),vDesiredParameter.x/rLMG.m_scale0,initD1 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName1.c_str(),vDesiredParameter.y/rLMG.m_scale1,initD2 );	
				g_YLine+=20.0f;

				for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep )
					g_pAuxGeom->DrawLine(Vec3(xmove1+x,rLMG.m_min1,0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+x,rLMG.m_max1,0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
				for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep )
					g_pAuxGeom->DrawLine(Vec3(xmove1+rLMG.m_min0,y,0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+rLMG.m_max0,y,0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 

				g_pAuxGeom->DrawOBB(_obb2,Vec3(xmove1+vDesiredParameter.x,vDesiredParameter.y,0.05f),1,RGBA8(0x00,0x00,0x00,0x00),eBBD_Extremes_Color_Encoded);
			}

			uint32 initialized=rLMG.m_ParaGrid2D.size();
			if (initialized==0)
			{
				rLMG.m_ParaGrid2D.resize(rLMG.m_cells0*rLMG.m_cells1);
				uint32 c1=0;
				for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep,c1++ )
				{
					uint32 c0=0;
					for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep,c0++ )
					{
						GetWeights2D( Vec2(x,y),rLMG,arrWeights,0);
						//	GetWeights2DKNN( Vec2(x,y),rLMG,arrWeights,0);
						uint32 cell=c1*rLMG.m_cells0+c0;
						rLMG.m_ParaGrid2D[cell].i0=0;	
						rLMG.m_ParaGrid2D[cell].i1=0;	
						rLMG.m_ParaGrid2D[cell].i2=0;	
						rLMG.m_ParaGrid2D[cell].i3=0;	
						rLMG.m_ParaGrid2D[cell].w0=0.0f;	
						rLMG.m_ParaGrid2D[cell].w1=0.0f;	
						rLMG.m_ParaGrid2D[cell].w2=0.0f;	
						rLMG.m_ParaGrid2D[cell].w3=0.0f;	

						uint32 c=0;
						uint8* pI=&(rLMG.m_ParaGrid2D[cell].i0);	
						float* pW=&(rLMG.m_ParaGrid2D[cell].w0);	
						for (uint32 i=0; i<numExamples; i++)
						{
							f32 w=arrWeights[i];
							if (w)
							{
								if (c>3)
									CryFatalError("Invalid Weights");
								pI[c]=i;	
								pW[c]=w;	
								c++;
							}
						}

						/*
						f32 sum=0.0f;
						sum += rLMG.m_ParaGrid2D[cell].w0;
						sum += rLMG.m_ParaGrid2D[cell].w1;
						sum += rLMG.m_ParaGrid2D[cell].w2;
						sum += rLMG.m_ParaGrid2D[cell].w3;
						if ( fabsf(sum-1.0f)>0.001f )
						{
						g_pIRenderer->Draw2dLabel( 1,g_YLine, 3.0f, fCol1111, false,"invalid sum: %f",sum );	
						g_YLine+=31.0f;
						}*/
					}
				}
			}


			if (Console::GetInst().ca_DrawVEGInfo)
			{
				GetWeights2D( vDesiredParameter,rLMG,arrWeights,xmove1);
				VExample2D ve; 
				ve.i0=0;		ve.i1=0;		ve.i2=0;		ve.i3=0;	
				ve.w0=0.0f;	ve.w1=0.0f;	ve.w2=0.0f;	ve.w3=0.0f;	
				uint32 c=0;
				uint8* pI=&(ve.i0);	
				float* pW=&(ve.w0);	
				for (uint32 i=0; i<numExamples; i++)
				{
					if (arrWeights[i])
					{
						pI[c]=i;	
						pW[c]=arrWeights[i];	
						c++;
					}
				}
			//	float fColDebug6[4]={1,0,1,1};
			//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fColDebug6, false,"weights: %f %f %f %f",ve.w0,ve.w1,ve.w2,ve.w3 );	
			//	g_YLine+=21.0f;
			}


			//---------------------------------------------------------------------------------------------
			//---                   visualize the virtual-examples                                  -------
			//---------------------------------------------------------------------------------------------
			uint32 numVExamples = rLMG.m_ParaGrid2D.size();
			if (numVExamples)
			{
				if (Console::GetInst().ca_DrawVEGInfo ) 
				{
					for (uint32 n=0; n<numVExamples; n++)
					{
						VExample2D ve = rLMG.m_ParaGrid2D[n];
						Vec3 v0=Vec3(rLMG.m_arrParameter[ve.i0].m_Para.x,rLMG.m_arrParameter[ve.i0].m_Para.y,0);
						Vec3 v1=Vec3(rLMG.m_arrParameter[ve.i1].m_Para.x,rLMG.m_arrParameter[ve.i1].m_Para.y,0);
						Vec3 v2=Vec3(rLMG.m_arrParameter[ve.i2].m_Para.x,rLMG.m_arrParameter[ve.i2].m_Para.y,0);
						Vec3 v3=Vec3(rLMG.m_arrParameter[ve.i3].m_Para.x,rLMG.m_arrParameter[ve.i3].m_Para.y,0);
						Vec3 ip = (v0*ve.w0 + v1*ve.w1 + v2*ve.w2 + v3*ve.w3) +Vec3(xmove1,0,0.05f);  
						g_pAuxGeom->DrawOBB(_obb1,ip,1,RGBA8(0x00,0x00,0x7f,0x00),eBBD_Extremes_Color_Encoded);
					}
					uint32 mem=rLMG.m_ParaGrid2D.get_alloc_size();
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"mem: %d",mem );	
					g_YLine+=21.0f;
				}

				//---------------------------------------------------------------------------------------------
				//---                   this is the 2D-parameterizer     --------------------------------------
				//---------------------------------------------------------------------------------------------
				if (1)
				{
					f32 cel0=f32(rLMG.m_cells0-1);
					f32 fx=(vDesiredParameter.x-rLMG.m_min0) / ((rLMG.m_max0-rLMG.m_min0)/cel0);
					fx=clamp(fx,0.0f,cel0-0.001f);
					int32 ix	=	int32(fx);
					f32 px		=	fx-f32(ix);

					f32 cel1=f32(rLMG.m_cells1-1);
					f32 fy=(vDesiredParameter.y-rLMG.m_min1) / ((rLMG.m_max1-rLMG.m_min1)/cel1);
					fy=clamp(fy,0.0f,cel1-0.001f);
					int32 iy	=	int32(fy);
					f32 py		=	fy-f32(iy);

					//		g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"dpx:%f dpy:%f   ix:%d iy:%d  px:%f py:%f",vDesiredParameter.x,vDesiredParameter.y,ix,iy, px,py );	
					//		g_YLine+=21.0f;

					for (uint32 i=0; i<numExamples; i++)	arrWeights[i]=0;

					VExample2D ve;

					f32 ew0=(1-px)*(1-py);	
					int idx0=(rLMG.m_cells0*(iy+0))+(ix+0);
					f32 ew1=   px *(1-py);	
					int idx1=(rLMG.m_cells0*(iy+0))+(ix+1);

					f32 ew2=(1-px)*py;	
					int idx2=(rLMG.m_cells0*(iy+1))+(ix+0);
					f32 ew3=   px *py;	
					int idx3=(rLMG.m_cells0*(iy+1))+(ix+1);

					ve = rLMG.m_ParaGrid2D[idx0];
					arrWeights[ve.i0]+=f32(ve.w0)*ew0;	
					arrWeights[ve.i1]+=f32(ve.w1)*ew0;	
					arrWeights[ve.i2]+=f32(ve.w2)*ew0;	
					arrWeights[ve.i3]+=f32(ve.w3)*ew0;	

					ve = rLMG.m_ParaGrid2D[idx1];
					arrWeights[ve.i0]+=f32(ve.w0)*ew1;
					arrWeights[ve.i1]+=f32(ve.w1)*ew1;
					arrWeights[ve.i2]+=f32(ve.w2)*ew1;
					arrWeights[ve.i3]+=f32(ve.w3)*ew1;

					ve = rLMG.m_ParaGrid2D[idx2];
					arrWeights[ve.i0]+= f32(ve.w0)*ew2;	
					arrWeights[ve.i1]+= f32(ve.w1)*ew2;	
					arrWeights[ve.i2]+= f32(ve.w2)*ew2;	
					arrWeights[ve.i3]+= f32(ve.w3)*ew2;	

					ve = rLMG.m_ParaGrid2D[idx3];
					arrWeights[ve.i0]+= f32(ve.w0)*ew3;
					arrWeights[ve.i1]+= f32(ve.w1)*ew3;
					arrWeights[ve.i2]+= f32(ve.w2)*ew3;
					arrWeights[ve.i3]+= f32(ve.w3)*ew3;

				}
			}

			f32 sum=0.0f;
			for (uint32 i=0; i<numExamples; i++) 
				if (fabsf(arrWeights[i])<0.015f)		arrWeights[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
				sum+=arrWeights[i];
			if (sum==0)
				arrWeights[0]=1.0f,sum=1.0f;
			for (uint32 i=0; i<numExamples; i++)
				lmg.m_fBlendWeight[i]=arrWeights[i]/sum;	

			//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"sum: %f",sum);	
			//	g_YLine+=21.0f;
		} //function PARA


		void ExportWeight_PARA3D(const char* pFilePath, DynArray<VExample3D>& rParaGrid3D)
		{
			return;
			FILE* pFile = ::fopen(pFilePath, "w");
			if (!pFile)
				return;
			fprintf(pFile, "<VGrid>\n");
			uint32 numVExamples = rParaGrid3D.size();
			for (uint32 i=0; i<numVExamples; ++i)
			{
				fprintf(pFile, "\t<VExample i0=\"%2d\" i1=\"%2d\" i2=\"%2d\" i3=\"%2d\" i4=\"%2d\" i5=\"%2d\" i6=\"%2d\" i7=\"%2d\"    w0=\"%10.7f\" w1=\"%10.7f\" w2=\"%10.7f\" w3=\"%10.7f\" w4=\"%10.7f\" w5=\"%10.7f\" w6=\"%10.7f\" w7=\"%10.7f\"/>\n",
					rParaGrid3D[i].i0, 
					rParaGrid3D[i].i1, 
					rParaGrid3D[i].i2, 
					rParaGrid3D[i].i3, 
					rParaGrid3D[i].i4, 
					rParaGrid3D[i].i5, 
					rParaGrid3D[i].i6, 
					rParaGrid3D[i].i7, 
					rParaGrid3D[i].w0, 
					rParaGrid3D[i].w1, 
					rParaGrid3D[i].w2, 
					rParaGrid3D[i].w3, 
					rParaGrid3D[i].w4, 
					rParaGrid3D[i].w5, 
					rParaGrid3D[i].w6, 
					rParaGrid3D[i].w7);
			}
			fprintf(pFile, "</VGrid>\n");
			::fclose(pFile);
		}



		void ComputeWeight_PARA3D(SParametric& lmg, GlobalAnimationHeaderLMG& rLMG)
		{
			float fCol1111[4] = {1,1,1,1};
			float fCol1011[4] = {1,0,1,1};
			uint32 nDimensions = rLMG.m_Dimensions;
			uint32 numExamples = rLMG.m_arrBSAnimations.size();

			static Ang3 angles=Ang3(0,0,0);
			angles.x+=0.01f;
			angles.y+=0.02f;
			angles.z+=0.03f;
			Matrix33 _m33=Matrix33::CreateRotationXYZ(angles);
			AABB aabb1 = AABB(Vec3( -0.02f, -0.02f, -0.02f),Vec3( 0.02f, 0.02f, 0.02f));
			OBB _obb1=OBB::CreateOBBfromAABB( _m33,aabb1 );
			AABB aabb2 = AABB(Vec3( -0.05f, -0.05f, -0.05f),Vec3( 0.05f, 0.05f, 0.05f));
			OBB _obb2=OBB::CreateOBBfromAABB( _m33,aabb2 );


			//---------------------------------------------------

			f32 arrWeights[0xff];
			Vec3 vDesiredParameter=Vec3(0,0,0);

			/*
			enum EMotionParamID
			{
			eMotionParamID_TravelAngle = 0,
			eMotionParamID_TravelDistScale,
			eMotionParamID_TravelSpeed,
			eMotionParamID_TravelDist,
			eMotionParamID_TravelSlope,
			eMotionParamID_WeightShift,
			eMotionParamID_TurnSpeed,
			eMotionParamID_TurnAngle,
			eMotionParamID_Duration,
			eMotionParamID_Curving,
			eMotionParamID_Height,
			eMotionParamID_Scale,

			eMotionParamID_COUNT,
			};*/


			//-------------------------------------------------------------
			//Dimension=1
			uint32 initD1=0;
			if (rLMG.m_strParaName0=="MoveSpeed")
			{
				vDesiredParameter.x = lmg.m_params[eMotionParamID_TravelSpeed].value;
				initD1 = lmg.m_params[eMotionParamID_TravelSpeed].initialized;
			}
			vDesiredParameter.x*=rLMG.m_scale0;
			vDesiredParameter.x=min(rLMG.m_max0,vDesiredParameter.x);
			vDesiredParameter.x=max(rLMG.m_min0,vDesiredParameter.x);

			//-------------------------------------------------------------
			//Dimension=2
			uint32 initD2=0;
			if (rLMG.m_strParaName1=="TurnSpeed")
			{
				vDesiredParameter.y=lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD2 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName1=="TravelAngle")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelAngle].value;
				initD2 = lmg.m_params[eMotionParamID_TravelAngle].initialized;
			}
			if (rLMG.m_strParaName1=="TravelSlope")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD2 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.y*=rLMG.m_scale1;
			vDesiredParameter.y=min(rLMG.m_max1,vDesiredParameter.y);
			vDesiredParameter.y=max(rLMG.m_min1,vDesiredParameter.y);


			//-------------------------------------------------------------
			//--- Dimension=3                                           ---
			//-------------------------------------------------------------
			uint32 initD3=0;
			if (rLMG.m_strParaName2=="TurnSpeed")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD3 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName2=="TravelAngle")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TravelAngle].value;
				initD3 = lmg.m_params[eMotionParamID_TravelAngle].initialized;
			}
			if (rLMG.m_strParaName2=="TravelSlope")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD3 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.z*=rLMG.m_scale2;
			vDesiredParameter.z=min(rLMG.m_max2,vDesiredParameter.z);
			vDesiredParameter.z=max(rLMG.m_min2,vDesiredParameter.z);


			f32 fThreshold = rLMG.m_fThreshold;
			if (fThreshold>-100 && fThreshold<100)
			{
				f32 tdy=fabsf(vDesiredParameter.y);
				if (tdy>fThreshold)
					vDesiredParameter.z=0;
				else
					vDesiredParameter.z*=1.0f-(tdy/fThreshold);
			}


			f32 xmove1=3;
			f32 xstep=(rLMG.m_max0-rLMG.m_min0)/f32(rLMG.m_cells0-1);
			f32 ystep=(rLMG.m_max1-rLMG.m_min1)/f32(rLMG.m_cells1-1);
			f32 zstep=(rLMG.m_max2-rLMG.m_min2)/f32(rLMG.m_cells2-1);
			if (Console::GetInst().ca_DrawVEGInfo ) 
			{
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName0.c_str(),vDesiredParameter.x/rLMG.m_scale0,initD1 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName1.c_str(),vDesiredParameter.y/rLMG.m_scale1,initD2 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName2.c_str(),vDesiredParameter.z/rLMG.m_scale2,initD3 );	
				g_YLine+=20.0f;

				for (f32 z=rLMG.m_min2; z<=(rLMG.m_max2+0.001f); z=z+zstep )
				{
					for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep )
						g_pAuxGeom->DrawLine(Vec3(xmove1+x,rLMG.m_min1,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+x,rLMG.m_max1,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 

					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep )
						g_pAuxGeom->DrawLine(Vec3(xmove1+rLMG.m_min0,y,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+rLMG.m_max0,y,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
				}
				g_pAuxGeom->DrawOBB(_obb2,Vec3(xmove1+vDesiredParameter.x,vDesiredParameter.y,vDesiredParameter.z),1,RGBA8(0x00,0x00,0x00,0x00),eBBD_Extremes_Color_Encoded);
			}



			uint32 initialized=rLMG.m_ParaGrid3D_1.size();
			if (initialized==0)
			{
				rLMG.m_ParaGrid3D_1.resize(rLMG.m_cells0*rLMG.m_cells1*rLMG.m_cells2);
				uint32 c2=0;
				for (f32 z=rLMG.m_min2; z<=(rLMG.m_max2+0.001f); z=z+zstep,c2++ )
				{
					uint32 c1=0;
					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep,c1++ )
					{
						uint32 c0=0;
						for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep,c0++ )
						{
							GetWeights3D_1( Vec3(x,y,z),rLMG,arrWeights,xmove1);
							uint32 cell=c2*rLMG.m_cells1*rLMG.m_cells0 + c1*rLMG.m_cells0 + c0;
							rLMG.m_ParaGrid3D_1[cell].i0=0;	
							rLMG.m_ParaGrid3D_1[cell].i1=0;	
							rLMG.m_ParaGrid3D_1[cell].i2=0;	
							rLMG.m_ParaGrid3D_1[cell].i3=0;
							rLMG.m_ParaGrid3D_1[cell].i4=0;	
							rLMG.m_ParaGrid3D_1[cell].i5=0;	
							rLMG.m_ParaGrid3D_1[cell].i6=0;	
							rLMG.m_ParaGrid3D_1[cell].i7=0;

							rLMG.m_ParaGrid3D_1[cell].w0=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w1=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w2=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w3=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w4=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w5=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w6=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w7=0.0f;	

							uint32 c=0;
							uint8* pI=&(rLMG.m_ParaGrid3D_1[cell].i0);	
							float* pW=&(rLMG.m_ParaGrid3D_1[cell].w0);	
							for (uint32 i=0; i<numExamples; i++)
							{
								f32 w=arrWeights[i];
								if (w)
								{
									if (c>7)
										CryFatalError("Invalid Weights");
									pI[c]=i;	
									pW[c]=w;	
									c++;
								}
							}
						}
					}
				}
				ExportWeight_PARA3D("c:/vgrid.txt",rLMG.m_ParaGrid3D_1);
			}


			if (Console::GetInst().ca_DrawVEGInfo)
			{
				GetWeights3D_1( vDesiredParameter,rLMG,arrWeights,xmove1);

				VExample3D ve; 
				ve.i0=0;		ve.i1=0;		ve.i2=0;		ve.i3=0;		ve.i4=0;		ve.i5=0;		ve.i6=0;		ve.i7=0; 	
				ve.w0=0.0f;	ve.w1=0.0f;	ve.w2=0.0f;	ve.w3=0.0f; ve.w4=0.0f; ve.w5=0.0f; ve.w6=0.0f; ve.w7=0.0f;
				uint32 c=0;
				uint8* pI=&(ve.i0);	
				float* pW=&(ve.w0);	
				for (uint32 i=0; i<numExamples; i++)
				{
					if (arrWeights[i])
					{
						if (c>7)
							CryFatalError("Invalid Weights");
						pI[c]=i;	
						pW[c]=arrWeights[i];	
						c++;
					}
				}
				//	float fColDebug6[4]={1,0,1,1};
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fColDebug6, false,"weights: %f %f %f %f",ve.w0,ve.w1,ve.w2,ve.w3,ve.w3 );	
				//	g_YLine+=21.0f;
			}


			//---------------------------------------------------------------------------------------------
			//---                   visualize the virtual-examples                                  -------
			//---------------------------------------------------------------------------------------------
			uint32 numVExamples = rLMG.m_ParaGrid3D_1.size();
			if (numVExamples)
			{
				if (Console::GetInst().ca_DrawVEGInfo ) 
				{
					for (uint32 n=0; n<numVExamples; n++)
					{
						VExample3D ve = rLMG.m_ParaGrid3D_1[n];
						Vec3 v0=Vec3(xmove1+rLMG.m_arrParameter[ve.i0].m_Para.x,rLMG.m_arrParameter[ve.i0].m_Para.y,rLMG.m_arrParameter[ve.i0].m_Para.z);
						Vec3 v1=Vec3(xmove1+rLMG.m_arrParameter[ve.i1].m_Para.x,rLMG.m_arrParameter[ve.i1].m_Para.y,rLMG.m_arrParameter[ve.i1].m_Para.z);
						Vec3 v2=Vec3(xmove1+rLMG.m_arrParameter[ve.i2].m_Para.x,rLMG.m_arrParameter[ve.i2].m_Para.y,rLMG.m_arrParameter[ve.i2].m_Para.z);
						Vec3 v3=Vec3(xmove1+rLMG.m_arrParameter[ve.i3].m_Para.x,rLMG.m_arrParameter[ve.i3].m_Para.y,rLMG.m_arrParameter[ve.i3].m_Para.z);
						Vec3 v4=Vec3(xmove1+rLMG.m_arrParameter[ve.i4].m_Para.x,rLMG.m_arrParameter[ve.i4].m_Para.y,rLMG.m_arrParameter[ve.i4].m_Para.z);
						Vec3 v5=Vec3(xmove1+rLMG.m_arrParameter[ve.i5].m_Para.x,rLMG.m_arrParameter[ve.i5].m_Para.y,rLMG.m_arrParameter[ve.i5].m_Para.z);
						Vec3 v6=Vec3(xmove1+rLMG.m_arrParameter[ve.i6].m_Para.x,rLMG.m_arrParameter[ve.i6].m_Para.y,rLMG.m_arrParameter[ve.i6].m_Para.z);
						Vec3 v7=Vec3(xmove1+rLMG.m_arrParameter[ve.i7].m_Para.x,rLMG.m_arrParameter[ve.i7].m_Para.y,rLMG.m_arrParameter[ve.i7].m_Para.z);
						Vec3 ip = (v0*ve.w0 + v1*ve.w1 + v2*ve.w2 + v3*ve.w3 + v4*ve.w4 + v5*ve.w5 + v6*ve.w6 + v7*ve.w7) +Vec3(0,0,0.05f);  
						g_pAuxGeom->DrawOBB(_obb1,ip,1,RGBA8(0x00,0x00,0x7f,0x00),eBBD_Extremes_Color_Encoded);
					}
					uint32 mem=rLMG.m_ParaGrid3D_1.get_alloc_size();
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"mem: %d",mem );	
					g_YLine+=21.0f;
				}

				//---------------------------------------------------------------------------------------------
				//---                   this is the 3D-parameterizer     --------------------------------------
				//---------------------------------------------------------------------------------------------
				if (1)
				{
					f32 cel0=f32(rLMG.m_cells0-1);
					f32 fx=(vDesiredParameter.x-rLMG.m_min0) / ((rLMG.m_max0-rLMG.m_min0)/cel0);
					fx=clamp(fx,0.0f,cel0-0.001f);
					int32 ix	=	int32(fx);
					f32 px		=	fx-f32(ix);

					f32 cel1=f32(rLMG.m_cells1-1);
					f32 fy=(vDesiredParameter.y-rLMG.m_min1) / ((rLMG.m_max1-rLMG.m_min1)/cel1);
					fy=clamp(fy,0.0f,cel1-0.001f);
					int32 iy	=	int32(fy);
					f32 py		=	fy-f32(iy);

					f32 cel2=f32(rLMG.m_cells2-1);
					f32 fz=(vDesiredParameter.z-rLMG.m_min2) / ((rLMG.m_max2-rLMG.m_min2)/cel2);
					fz=clamp(fz,0.0f,cel2-0.001f);
					int32 iz	=	int32(fz);
					f32 pz		=	fz-f32(iz);

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"fx: %f   fy: %f   fz: %f" , fx,fy,fz );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"dpx:%f dpy:%f dpz:%f     ix:%d iy:%d iz:%d    px:%f py:%f pz:%f",vDesiredParameter.x,vDesiredParameter.y,vDesiredParameter.z,   ix,iy,iz,  px,py,pz );	
					//	g_YLine+=21.0f;

					for (uint32 i=0; i<numExamples; i++) 
						arrWeights[i]=0;

					uint32 idx;
					VExample3D ve;

					f32 ew0=(1.0f-pz)*(1-px)*(1-py);	
					idx =(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+=f32(ve.w0)*ew0;	
					arrWeights[ve.i1]+=f32(ve.w1)*ew0;	
					arrWeights[ve.i2]+=f32(ve.w2)*ew0;	
					arrWeights[ve.i3]+=f32(ve.w3)*ew0;	
					arrWeights[ve.i4]+=f32(ve.w4)*ew0;	
					arrWeights[ve.i5]+=f32(ve.w5)*ew0;	
					arrWeights[ve.i6]+=f32(ve.w6)*ew0;	
					arrWeights[ve.i7]+=f32(ve.w7)*ew0;	

					f32 ew1=(1.0f-pz)*px*(1-py);	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+=f32(ve.w0)*ew1;
					arrWeights[ve.i1]+=f32(ve.w1)*ew1;
					arrWeights[ve.i2]+=f32(ve.w2)*ew1;
					arrWeights[ve.i3]+=f32(ve.w3)*ew1;
					arrWeights[ve.i4]+=f32(ve.w4)*ew1;
					arrWeights[ve.i5]+=f32(ve.w5)*ew1;
					arrWeights[ve.i6]+=f32(ve.w6)*ew1;
					arrWeights[ve.i7]+=f32(ve.w7)*ew1;

					f32 ew2=(1.0f-pz)*(1-px)*py;	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+= f32(ve.w0)*ew2;	
					arrWeights[ve.i1]+= f32(ve.w1)*ew2;	
					arrWeights[ve.i2]+= f32(ve.w2)*ew2;	
					arrWeights[ve.i3]+= f32(ve.w3)*ew2;	
					arrWeights[ve.i4]+= f32(ve.w4)*ew2;	
					arrWeights[ve.i5]+= f32(ve.w5)*ew2;	
					arrWeights[ve.i6]+= f32(ve.w6)*ew2;	
					arrWeights[ve.i7]+= f32(ve.w7)*ew2;	

					f32 ew3=(1.0f-pz)*px*py;	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0+(ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+= f32(ve.w0)*ew3;
					arrWeights[ve.i1]+= f32(ve.w1)*ew3;
					arrWeights[ve.i2]+= f32(ve.w2)*ew3;
					arrWeights[ve.i3]+= f32(ve.w3)*ew3;
					arrWeights[ve.i4]+= f32(ve.w4)*ew3;
					arrWeights[ve.i5]+= f32(ve.w5)*ew3;
					arrWeights[ve.i6]+= f32(ve.w6)*ew3;
					arrWeights[ve.i7]+= f32(ve.w7)*ew3;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew2: %f idx2: %d  ew3: %f  idx3: %d",ew2,idx2, ew3,idx3 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew0: %f idx0: %d  ew1: %f  idx1: %d",ew0,idx0, ew1,idx1 );	
					//	g_YLine+=21.0f;

					//---------------------------------------------------------

					f32 ew4=pz*(1-px)*(1-py);	
					idx =(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+=f32(ve.w0)*ew4;	
					arrWeights[ve.i1]+=f32(ve.w1)*ew4;	
					arrWeights[ve.i2]+=f32(ve.w2)*ew4;	
					arrWeights[ve.i3]+=f32(ve.w3)*ew4;	
					arrWeights[ve.i4]+=f32(ve.w4)*ew4;	
					arrWeights[ve.i5]+=f32(ve.w5)*ew4;	
					arrWeights[ve.i6]+=f32(ve.w6)*ew4;	
					arrWeights[ve.i7]+=f32(ve.w7)*ew4;	

					f32 ew5=pz*px*(1-py);	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+=f32(ve.w0)*ew5;
					arrWeights[ve.i1]+=f32(ve.w1)*ew5;
					arrWeights[ve.i2]+=f32(ve.w2)*ew5;
					arrWeights[ve.i3]+=f32(ve.w3)*ew5;
					arrWeights[ve.i4]+=f32(ve.w4)*ew5;
					arrWeights[ve.i5]+=f32(ve.w5)*ew5;
					arrWeights[ve.i6]+=f32(ve.w6)*ew5;
					arrWeights[ve.i7]+=f32(ve.w7)*ew5;

					f32 ew6=pz*(1-px)*py;	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+= f32(ve.w0)*ew6;	
					arrWeights[ve.i1]+= f32(ve.w1)*ew6;	
					arrWeights[ve.i2]+= f32(ve.w2)*ew6;	
					arrWeights[ve.i3]+= f32(ve.w3)*ew6;	
					arrWeights[ve.i4]+= f32(ve.w4)*ew6;	
					arrWeights[ve.i5]+= f32(ve.w5)*ew6;	
					arrWeights[ve.i6]+= f32(ve.w6)*ew6;	
					arrWeights[ve.i7]+= f32(ve.w7)*ew6;	

					f32 ew7=pz*px*py;	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights[ve.i0]+= f32(ve.w0)*ew7;
					arrWeights[ve.i1]+= f32(ve.w1)*ew7;
					arrWeights[ve.i2]+= f32(ve.w2)*ew7;
					arrWeights[ve.i3]+= f32(ve.w3)*ew7;
					arrWeights[ve.i4]+= f32(ve.w4)*ew7;
					arrWeights[ve.i5]+= f32(ve.w5)*ew7;
					arrWeights[ve.i6]+= f32(ve.w6)*ew7;
					arrWeights[ve.i7]+= f32(ve.w7)*ew7;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw6: %f idx6: %d  xw7: %f  idx7: %d", ew6,idx6, ew7,idx7 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw4: %f idx4: %d  xw5: %f  idx5: %d", ew4,idx4, ew5,idx5 );	
					//	g_YLine+=21.0f;

					if (0)
					{
						uint8 arrI[40];
						f32 arrW[40];
						for (uint32 i=0; i<40; i++)
						{
							arrI[i]=0;
							arrW[i]=0;
						}

						uint32 c=0;
						for (uint32 i=0; i<numExamples; i++)
						{
							if (arrWeights[i])
							{
								arrI[c]=i;	
								arrW[c]=arrWeights[i];	
								c++;
							}
						}
						g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1011, false,"indices: %d %d %d %d %d %d",arrI[0],arrI[1],arrI[2],arrI[3],arrI[4],arrI[5] );	
						g_YLine+=21.0f;
						g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1011, false,"weights: %f %f %f %f %f %f",arrW[0],arrW[1],arrW[2],arrW[3],arrW[4],arrW[5] );	
						g_YLine+=21.0f;
					}
				}
			}

			f32 sum=0.0f;
			for (uint32 i=0; i<numExamples; i++) 
				if (fabsf(arrWeights[i])<0.000001f)		arrWeights[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
				sum+=arrWeights[i];
			if (sum==0)
				arrWeights[0]=1.0f,sum=1.0f;
			for (uint32 i=0; i<numExamples; i++)
				lmg.m_fBlendWeight[i]=arrWeights[i]/sum;	

			//g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"sum: %f",sum);	
			//g_YLine+=21.0f;
		} //function PARA

		//---------------------------------------------------------------------
		//---------------------------------------------------------------------
		//---------------------------------------------------------------------

		void ComputeWeight_PARA4D(SParametric& lmg, GlobalAnimationHeaderLMG& rLMG)
		{
			float fCol1111[4] = {1,1,1,1};
			float fCol1011[4] = {1,0,1,1};
			uint32 nDimensions = rLMG.m_Dimensions;
			uint32 numExamples = rLMG.m_arrBSAnimations.size();

			static Ang3 angles=Ang3(0,0,0);
			angles.x+=0.01f;
			angles.y+=0.02f;
			angles.z+=0.03f;
			Matrix33 _m33=Matrix33::CreateRotationXYZ(angles);
			AABB aabb1 = AABB(Vec3( -0.02f, -0.02f, -0.02f),Vec3( 0.02f, 0.02f, 0.02f));
			OBB _obb1=OBB::CreateOBBfromAABB( _m33,aabb1 );
			AABB aabb2 = AABB(Vec3( -0.05f, -0.05f, -0.05f),Vec3( 0.05f, 0.05f, 0.05f));
			OBB _obb2=OBB::CreateOBBfromAABB( _m33,aabb2 );


			//---------------------------------------------------

			f32 arrWeights[256];
			f32 arrWeights1[256];
			f32 arrWeights2[256];
			Vec4 vDesiredParameter=Vec4(0,0,0,0);


			//-------------------------------------------------------------
			//Dimension=1
			uint32 initD1=0;
			if (rLMG.m_strParaName0=="MoveSpeed")
			{
				vDesiredParameter.x = lmg.m_params[eMotionParamID_TravelSpeed].value;
				initD1 = lmg.m_params[eMotionParamID_TravelSpeed].initialized;
			}
			vDesiredParameter.x*=rLMG.m_scale0;
			vDesiredParameter.x=min(rLMG.m_max0,vDesiredParameter.x);
			vDesiredParameter.x=max(rLMG.m_min0,vDesiredParameter.x);

			//-------------------------------------------------------------
			//Dimension=2
			uint32 initD2=0;
			if (rLMG.m_strParaName1=="TurnSpeed")
			{
				vDesiredParameter.y=lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD2 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName1=="TravelAngle")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelAngle].value;
				initD2 = lmg.m_params[eMotionParamID_TravelAngle].initialized;
			}
			if (rLMG.m_strParaName1=="TravelSlope")
			{
				vDesiredParameter.y = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD2 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.y*=rLMG.m_scale1;
			vDesiredParameter.y=min(rLMG.m_max1,vDesiredParameter.y);
			vDesiredParameter.y=max(rLMG.m_min1,vDesiredParameter.y);


			//-------------------------------------------------------------
			//--- Dimension=3                                           ---
			//-------------------------------------------------------------
			uint32 initD3=0;
			if (rLMG.m_strParaName2=="TurnSpeed")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD3 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName2=="TravelAngle")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TravelAngle].value;
				initD3 = lmg.m_params[eMotionParamID_TravelAngle].initialized;
			}
			if (rLMG.m_strParaName2=="TravelSlope")
			{
				vDesiredParameter.z = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD3 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.z*=rLMG.m_scale2;
			vDesiredParameter.z=min(rLMG.m_max2,vDesiredParameter.z);
			vDesiredParameter.z=max(rLMG.m_min2,vDesiredParameter.z);

			//-------------------------------------------------------------
			//--- Dimension=4                                           ---
			//-------------------------------------------------------------
			uint32 initD4=0;
			if (rLMG.m_strParaName3=="TurnSpeed")
			{
				vDesiredParameter.w = lmg.m_params[eMotionParamID_TurnSpeed].value;
				initD4 = lmg.m_params[eMotionParamID_TurnSpeed].initialized;
			}
			if (rLMG.m_strParaName3=="TravelSlope")
			{
				vDesiredParameter.w = lmg.m_params[eMotionParamID_TravelSlope].value;
				initD4 = lmg.m_params[eMotionParamID_TravelSlope].initialized;
			}
			vDesiredParameter.w*=rLMG.m_scale3;
			vDesiredParameter.w=min(rLMG.m_max3,vDesiredParameter.w);
			vDesiredParameter.w=max(rLMG.m_min3,vDesiredParameter.w);





			f32 fThreshold = rLMG.m_fThreshold;
			if (fThreshold>-100 && fThreshold<100)
			{
				f32 tdy=fabsf(vDesiredParameter.y);
				if (tdy>fThreshold)
					vDesiredParameter.z=0;
				else
					vDesiredParameter.z*=1.0f-(tdy/fThreshold);

				if (tdy>fThreshold)
					vDesiredParameter.w=0;
				else
					vDesiredParameter.w*=1.0f-(tdy/fThreshold);
			}

			f32 xmove1=3;
			f32 xmove2=-(rLMG.m_max0+3);
			f32 xstep=(rLMG.m_max0-rLMG.m_min0)/f32(rLMG.m_cells0-1);
			f32 ystep=(rLMG.m_max1-rLMG.m_min1)/f32(rLMG.m_cells1-1);
			f32 zstep=(rLMG.m_max2-rLMG.m_min2)/f32(rLMG.m_cells2-1);
			f32 wstep=(rLMG.m_max3-rLMG.m_min3)/f32(rLMG.m_cells3-1);
			if (Console::GetInst().ca_DrawVEGInfo ) 
			{
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName0.c_str(),vDesiredParameter.x/rLMG.m_scale0,initD1 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName1.c_str(),vDesiredParameter.y/rLMG.m_scale1,initD2 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName2.c_str(),vDesiredParameter.z/rLMG.m_scale2,initD3 );	
				g_YLine+=20.0f;
				g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"%s: %f %d",rLMG.m_strParaName3.c_str(),vDesiredParameter.w/rLMG.m_scale3,initD4 );	
				g_YLine+=20.0f;

				for (f32 z=rLMG.m_min2; z<=(rLMG.m_max2+0.001f); z=z+zstep )
				{
					for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep )
						g_pAuxGeom->DrawLine(Vec3(xmove1+x,rLMG.m_min1,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+x,rLMG.m_max1,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep )
						g_pAuxGeom->DrawLine(Vec3(xmove1+rLMG.m_min0,y,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove1+rLMG.m_max0,y,z+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
				}

				for (f32 w=rLMG.m_min3; w<=(rLMG.m_max3+0.001f); w=w+wstep )
				{
					for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep )
						g_pAuxGeom->DrawLine(Vec3(xmove2+x,rLMG.m_min1,w+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove2+x,rLMG.m_max1,w+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep )
						g_pAuxGeom->DrawLine(Vec3(xmove2+rLMG.m_min0,y,w+0.05f),RGBA8(0xff,0x00,0xff,0x00), Vec3(xmove2+rLMG.m_max0,y,w+0.05f),RGBA8(0xff,0x00,0xff,0x00), 1.0f); 
				}

				g_pAuxGeom->DrawOBB(_obb2,Vec3(vDesiredParameter.x+xmove1,vDesiredParameter.y,vDesiredParameter.z),1,RGBA8(0x00,0x00,0x00,0x00),eBBD_Extremes_Color_Encoded);
				g_pAuxGeom->DrawOBB(_obb2,Vec3(vDesiredParameter.x+xmove2,vDesiredParameter.y,vDesiredParameter.w),1,RGBA8(0xff,0xff,0x00,0x00),eBBD_Extremes_Color_Encoded);
			}

			uint32 initialized1=rLMG.m_ParaGrid3D_1.size();
			if (initialized1==0)
			{
				rLMG.m_ParaGrid3D_1.resize(rLMG.m_cells0*rLMG.m_cells1*rLMG.m_cells2);
				uint32 c2=0;
				for (f32 z=rLMG.m_min2; z<=(rLMG.m_max2+0.001f); z=z+zstep,c2++ )
				{
					uint32 c1=0;
					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep,c1++ )
					{
						uint32 c0=0;
						for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep,c0++ )
						{
							GetWeights3D_1( Vec3(x,y,z*2),rLMG,arrWeights1,xmove1);
							uint32 cell=c2*rLMG.m_cells1*rLMG.m_cells0 + c1*rLMG.m_cells0 + c0;
							rLMG.m_ParaGrid3D_1[cell].i0=0;	
							rLMG.m_ParaGrid3D_1[cell].i1=0;	
							rLMG.m_ParaGrid3D_1[cell].i2=0;	
							rLMG.m_ParaGrid3D_1[cell].i3=0;
							rLMG.m_ParaGrid3D_1[cell].i4=0;	
							rLMG.m_ParaGrid3D_1[cell].i5=0;	
							rLMG.m_ParaGrid3D_1[cell].i6=0;	
							rLMG.m_ParaGrid3D_1[cell].i7=0;

							rLMG.m_ParaGrid3D_1[cell].w0=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w1=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w2=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w3=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w4=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w5=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w6=0.0f;	
							rLMG.m_ParaGrid3D_1[cell].w7=0.0f;	

							uint32 c=0;
							uint8* pI=&(rLMG.m_ParaGrid3D_1[cell].i0);	
							float* pW=&(rLMG.m_ParaGrid3D_1[cell].w0);	
							for (uint32 i=0; i<numExamples; i++)
							{
								f32 w1=arrWeights1[i];
								if (w1)
								{
									if (c>7)
										CryFatalError("Invalid Weights");
									pI[c]=i;	
									pW[c]=w1;	
									c++;
								}
							}
						}
					}
				}
				ExportWeight_PARA3D("c:/vgrid1.txt",rLMG.m_ParaGrid3D_1);
			}


			uint32 initialized2=rLMG.m_ParaGrid3D_2.size();
			if (initialized2==0)
			{
				rLMG.m_ParaGrid3D_2.resize(rLMG.m_cells0*rLMG.m_cells1*rLMG.m_cells3);
				uint32 c3=0;
				for (f32 w=rLMG.m_min3; w<=(rLMG.m_max3+0.001f); w=w+wstep,c3++ )
				{
					uint32 c1=0;
					for (f32 y=rLMG.m_min1; y<=(rLMG.m_max1+0.001f); y=y+ystep,c1++ )
					{
						uint32 c0=0;
						for (f32 x=rLMG.m_min0; x<=(rLMG.m_max0+0.001f); x=x+xstep,c0++ )
						{
							GetWeights3D_2( Vec3(x,y,w*2),rLMG,arrWeights2,xmove2);
							uint32 cell=c3*rLMG.m_cells1*rLMG.m_cells0 + c1*rLMG.m_cells0 + c0;
							rLMG.m_ParaGrid3D_2[cell].i0=0;	
							rLMG.m_ParaGrid3D_2[cell].i1=0;	
							rLMG.m_ParaGrid3D_2[cell].i2=0;	
							rLMG.m_ParaGrid3D_2[cell].i3=0;
							rLMG.m_ParaGrid3D_2[cell].i4=0;	
							rLMG.m_ParaGrid3D_2[cell].i5=0;	
							rLMG.m_ParaGrid3D_2[cell].i6=0;	
							rLMG.m_ParaGrid3D_2[cell].i7=0;

							rLMG.m_ParaGrid3D_2[cell].w0=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w1=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w2=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w3=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w4=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w5=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w6=0.0f;	
							rLMG.m_ParaGrid3D_2[cell].w7=0.0f;	

							uint32 c=0;
							uint8* pI=&(rLMG.m_ParaGrid3D_2[cell].i0);	
							float* pW=&(rLMG.m_ParaGrid3D_2[cell].w0);	
							for (uint32 i=0; i<numExamples; i++)
							{
								f32 w2=arrWeights2[i];
								if (w2)
								{
									if (c>7)
										CryFatalError("Invalid Weights");
									pI[c]=i;	
									pW[c]=w2;	
									c++;
								}
							}
						}
					}
				}
				ExportWeight_PARA3D("c:/vgrid2.txt",rLMG.m_ParaGrid3D_2);
			}


			//first 3d-space
			if (Console::GetInst().ca_DrawVEGInfo)
			{
				Vec3 para;
				para.x=vDesiredParameter.x;
				para.y=vDesiredParameter.y;
				para.z=vDesiredParameter.z*2;
				GetWeights3D_1( para,rLMG,arrWeights1,xmove1);

				VExample3D ve; 
				ve.i0=0;		ve.i1=0;		ve.i2=0;		ve.i3=0;		ve.i4=0;		ve.i5=0;		ve.i6=0;		ve.i7=0; 	
				ve.w0=0.0f;	ve.w1=0.0f;	ve.w2=0.0f;	ve.w3=0.0f; ve.w4=0.0f; ve.w5=0.0f; ve.w6=0.0f; ve.w7=0.0f;
				uint32 c=0;
				uint8* pI=&(ve.i0);	
				float* pW=&(ve.w0);	
				for (uint32 i=0; i<numExamples; i++)
				{
					if (arrWeights1[i])
					{
						if (c>7)
							CryFatalError("Invalid Weights");
						pI[c]=i;	
						pW[c]=arrWeights1[i];	
						c++;
					}
				}
				//	float fColDebug6[4]={1,0,1,1};
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fColDebug6, false,"weights: %f %f %f %f",ve.w0,ve.w1,ve.w2,ve.w3,ve.w3 );	
				//	g_YLine+=21.0f;
			}

			//second 3d-space
			if (Console::GetInst().ca_DrawVEGInfo)
			{
				Vec3 para;
				para.x=vDesiredParameter.x;
				para.y=vDesiredParameter.y;
				para.z=vDesiredParameter.w*2;
				GetWeights3D_2( para,rLMG,arrWeights2,xmove2);

				VExample3D ve; 
				ve.i0=0;		ve.i1=0;		ve.i2=0;		ve.i3=0;		ve.i4=0;		ve.i5=0;		ve.i6=0;		ve.i7=0; 	
				ve.w0=0.0f;	ve.w1=0.0f;	ve.w2=0.0f;	ve.w3=0.0f; ve.w4=0.0f; ve.w5=0.0f; ve.w6=0.0f; ve.w7=0.0f;
				uint32 c=0;
				uint8* pI=&(ve.i0);	
				float* pW=&(ve.w0);	
				for (uint32 i=0; i<numExamples; i++)
				{
					if (arrWeights2[i])
					{
						if (c>7)
							CryFatalError("Invalid Weights");
						pI[c]=i;	
						pW[c]=arrWeights2[i];	
						c++;
					}
				}
				//	float fColDebug6[4]={1,0,1,1};
				//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fColDebug6, false,"weights: %f %f %f %f",ve.w0,ve.w1,ve.w2,ve.w3,ve.w3 );	
				//	g_YLine+=21.0f;
			}

			//---------------------------------------------------------------------------------------------
			//---                   visualize the virtual-examples                                  -------
			//---------------------------------------------------------------------------------------------
			uint32 numVExamples1 = rLMG.m_ParaGrid3D_1.size();
			if (numVExamples1)
			{
				if (Console::GetInst().ca_DrawVEGInfo ) 
				{
					for (uint32 n=0; n<numVExamples1; n++)
					{
						VExample3D ve = rLMG.m_ParaGrid3D_1[n];
						Vec3 v0=Vec3(rLMG.m_arrParameter[ve.i0].m_Para.x,rLMG.m_arrParameter[ve.i0].m_Para.y,rLMG.m_arrParameter[ve.i0].m_Para.z*0.5f);
						Vec3 v1=Vec3(rLMG.m_arrParameter[ve.i1].m_Para.x,rLMG.m_arrParameter[ve.i1].m_Para.y,rLMG.m_arrParameter[ve.i1].m_Para.z*0.5f);
						Vec3 v2=Vec3(rLMG.m_arrParameter[ve.i2].m_Para.x,rLMG.m_arrParameter[ve.i2].m_Para.y,rLMG.m_arrParameter[ve.i2].m_Para.z*0.5f);
						Vec3 v3=Vec3(rLMG.m_arrParameter[ve.i3].m_Para.x,rLMG.m_arrParameter[ve.i3].m_Para.y,rLMG.m_arrParameter[ve.i3].m_Para.z*0.5f);
						Vec3 v4=Vec3(rLMG.m_arrParameter[ve.i4].m_Para.x,rLMG.m_arrParameter[ve.i4].m_Para.y,rLMG.m_arrParameter[ve.i4].m_Para.z*0.5f);
						Vec3 v5=Vec3(rLMG.m_arrParameter[ve.i5].m_Para.x,rLMG.m_arrParameter[ve.i5].m_Para.y,rLMG.m_arrParameter[ve.i5].m_Para.z*0.5f);
						Vec3 v6=Vec3(rLMG.m_arrParameter[ve.i6].m_Para.x,rLMG.m_arrParameter[ve.i6].m_Para.y,rLMG.m_arrParameter[ve.i6].m_Para.z*0.5f);
						Vec3 v7=Vec3(rLMG.m_arrParameter[ve.i7].m_Para.x,rLMG.m_arrParameter[ve.i7].m_Para.y,rLMG.m_arrParameter[ve.i7].m_Para.z*0.5f);
						Vec3 ip = (v0*ve.w0 + v1*ve.w1 + v2*ve.w2 + v3*ve.w3 + v4*ve.w4 + v5*ve.w5 + v6*ve.w6 + v7*ve.w7) + Vec3(xmove1,0,0.05f);  
						g_pAuxGeom->DrawOBB(_obb1,ip,1,RGBA8(0x00,0x00,0x7f,0x00),eBBD_Extremes_Color_Encoded);
					}
					uint32 mem=rLMG.m_ParaGrid3D_1.get_alloc_size();
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"mem: %d",mem );	
					g_YLine+=21.0f;
				}

				//---------------------------------------------------------------------------------------------
				//---                   this is the 3D-parameterizer     --------------------------------------
				//---------------------------------------------------------------------------------------------
				if (1)
				{
					f32 cel0=f32(rLMG.m_cells0-1);
					f32 fx=(vDesiredParameter.x-rLMG.m_min0) / ((rLMG.m_max0-rLMG.m_min0)/cel0);
					fx=clamp(fx,0.0f,cel0-0.001f);
					int32 ix	=	int32(fx);
					f32 px		=	fx-f32(ix);

					f32 cel1=f32(rLMG.m_cells1-1);
					f32 fy=(vDesiredParameter.y-rLMG.m_min1) / ((rLMG.m_max1-rLMG.m_min1)/cel1);
					fy=clamp(fy,0.0f,cel1-0.001f);
					int32 iy	=	int32(fy);
					f32 py		=	fy-f32(iy);

					f32 cel2=f32(rLMG.m_cells2-1);
					f32 fz=(vDesiredParameter.z-rLMG.m_min2) / ((rLMG.m_max2-rLMG.m_min2)/cel2);
					fz=clamp(fz,0.0f,cel2-0.001f);
					int32 iz	=	int32(fz);
					f32 pz		=	fz-f32(iz);

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"fx: %f   fy: %f   fz: %f" , fx,fy,fz );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"dpx:%f dpy:%f dpz:%f     ix:%d iy:%d iz:%d    px:%f py:%f pz:%f",vDesiredParameter.x,vDesiredParameter.y,vDesiredParameter.z,   ix,iy,iz,  px,py,pz );	
					//	g_YLine+=21.0f;

					for (uint32 i=0; i<numExamples; i++) 
						arrWeights1[i]=0;

					uint32 idx;
					VExample3D ve;

					f32 ew0=(1.0f-pz)*(1-px)*(1-py);	
					idx =(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+=f32(ve.w0)*ew0;	
					arrWeights1[ve.i1]+=f32(ve.w1)*ew0;	
					arrWeights1[ve.i2]+=f32(ve.w2)*ew0;	
					arrWeights1[ve.i3]+=f32(ve.w3)*ew0;	
					arrWeights1[ve.i4]+=f32(ve.w4)*ew0;	
					arrWeights1[ve.i5]+=f32(ve.w5)*ew0;	
					arrWeights1[ve.i6]+=f32(ve.w6)*ew0;	
					arrWeights1[ve.i7]+=f32(ve.w7)*ew0;	

					f32 ew1=(1.0f-pz)*px*(1-py);	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+=f32(ve.w0)*ew1;
					arrWeights1[ve.i1]+=f32(ve.w1)*ew1;
					arrWeights1[ve.i2]+=f32(ve.w2)*ew1;
					arrWeights1[ve.i3]+=f32(ve.w3)*ew1;
					arrWeights1[ve.i4]+=f32(ve.w4)*ew1;
					arrWeights1[ve.i5]+=f32(ve.w5)*ew1;
					arrWeights1[ve.i6]+=f32(ve.w6)*ew1;
					arrWeights1[ve.i7]+=f32(ve.w7)*ew1;

					f32 ew2=(1.0f-pz)*(1-px)*py;	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+= f32(ve.w0)*ew2;	
					arrWeights1[ve.i1]+= f32(ve.w1)*ew2;	
					arrWeights1[ve.i2]+= f32(ve.w2)*ew2;	
					arrWeights1[ve.i3]+= f32(ve.w3)*ew2;	
					arrWeights1[ve.i4]+= f32(ve.w4)*ew2;	
					arrWeights1[ve.i5]+= f32(ve.w5)*ew2;	
					arrWeights1[ve.i6]+= f32(ve.w6)*ew2;	
					arrWeights1[ve.i7]+= f32(ve.w7)*ew2;	

					f32 ew3=(1.0f-pz)*px*py;	
					idx=(iz+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0+(ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+= f32(ve.w0)*ew3;
					arrWeights1[ve.i1]+= f32(ve.w1)*ew3;
					arrWeights1[ve.i2]+= f32(ve.w2)*ew3;
					arrWeights1[ve.i3]+= f32(ve.w3)*ew3;
					arrWeights1[ve.i4]+= f32(ve.w4)*ew3;
					arrWeights1[ve.i5]+= f32(ve.w5)*ew3;
					arrWeights1[ve.i6]+= f32(ve.w6)*ew3;
					arrWeights1[ve.i7]+= f32(ve.w7)*ew3;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew2: %f idx2: %d  ew3: %f  idx3: %d",ew2,idx2, ew3,idx3 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew0: %f idx0: %d  ew1: %f  idx1: %d",ew0,idx0, ew1,idx1 );	
					//	g_YLine+=21.0f;

					//---------------------------------------------------------

					f32 ew4=pz*(1-px)*(1-py);	
					idx =(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+=f32(ve.w0)*ew4;	
					arrWeights1[ve.i1]+=f32(ve.w1)*ew4;	
					arrWeights1[ve.i2]+=f32(ve.w2)*ew4;	
					arrWeights1[ve.i3]+=f32(ve.w3)*ew4;	
					arrWeights1[ve.i4]+=f32(ve.w4)*ew4;	
					arrWeights1[ve.i5]+=f32(ve.w5)*ew4;	
					arrWeights1[ve.i6]+=f32(ve.w6)*ew4;	
					arrWeights1[ve.i7]+=f32(ve.w7)*ew4;	

					f32 ew5=pz*px*(1-py);	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+=f32(ve.w0)*ew5;
					arrWeights1[ve.i1]+=f32(ve.w1)*ew5;
					arrWeights1[ve.i2]+=f32(ve.w2)*ew5;
					arrWeights1[ve.i3]+=f32(ve.w3)*ew5;
					arrWeights1[ve.i4]+=f32(ve.w4)*ew5;
					arrWeights1[ve.i5]+=f32(ve.w5)*ew5;
					arrWeights1[ve.i6]+=f32(ve.w6)*ew5;
					arrWeights1[ve.i7]+=f32(ve.w7)*ew5;

					f32 ew6=pz*(1-px)*py;	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+= f32(ve.w0)*ew6;	
					arrWeights1[ve.i1]+= f32(ve.w1)*ew6;	
					arrWeights1[ve.i2]+= f32(ve.w2)*ew6;	
					arrWeights1[ve.i3]+= f32(ve.w3)*ew6;	
					arrWeights1[ve.i4]+= f32(ve.w4)*ew6;	
					arrWeights1[ve.i5]+= f32(ve.w5)*ew6;	
					arrWeights1[ve.i6]+= f32(ve.w6)*ew6;	
					arrWeights1[ve.i7]+= f32(ve.w7)*ew6;	

					f32 ew7=pz*px*py;	
					idx=(iz+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_1[idx];
					arrWeights1[ve.i0]+= f32(ve.w0)*ew7;
					arrWeights1[ve.i1]+= f32(ve.w1)*ew7;
					arrWeights1[ve.i2]+= f32(ve.w2)*ew7;
					arrWeights1[ve.i3]+= f32(ve.w3)*ew7;
					arrWeights1[ve.i4]+= f32(ve.w4)*ew7;
					arrWeights1[ve.i5]+= f32(ve.w5)*ew7;
					arrWeights1[ve.i6]+= f32(ve.w6)*ew7;
					arrWeights1[ve.i7]+= f32(ve.w7)*ew7;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw6: %f idx6: %d  xw7: %f  idx7: %d", ew6,idx6, ew7,idx7 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw4: %f idx4: %d  xw5: %f  idx5: %d", ew4,idx4, ew5,idx5 );	
					//	g_YLine+=21.0f;
				}
			}


			//---------------------------------------------------------------------------------------------
			//---                   visualize the virtual-examples                                  -------
			//---------------------------------------------------------------------------------------------
			uint32 numVExamples2 = rLMG.m_ParaGrid3D_2.size();
			if (numVExamples2)
			{
				if (Console::GetInst().ca_DrawVEGInfo ) 
				{
					for (uint32 n=0; n<numVExamples2; n++)
					{
						VExample3D ve = rLMG.m_ParaGrid3D_2[n];
						Vec3 v0=Vec3(rLMG.m_arrParameter[ve.i0].m_Para.x,rLMG.m_arrParameter[ve.i0].m_Para.y,rLMG.m_arrParameter[ve.i0].m_Para.w*0.5f);
						Vec3 v1=Vec3(rLMG.m_arrParameter[ve.i1].m_Para.x,rLMG.m_arrParameter[ve.i1].m_Para.y,rLMG.m_arrParameter[ve.i1].m_Para.w*0.5f);
						Vec3 v2=Vec3(rLMG.m_arrParameter[ve.i2].m_Para.x,rLMG.m_arrParameter[ve.i2].m_Para.y,rLMG.m_arrParameter[ve.i2].m_Para.w*0.5f);
						Vec3 v3=Vec3(rLMG.m_arrParameter[ve.i3].m_Para.x,rLMG.m_arrParameter[ve.i3].m_Para.y,rLMG.m_arrParameter[ve.i3].m_Para.w*0.5f);
						Vec3 v4=Vec3(rLMG.m_arrParameter[ve.i4].m_Para.x,rLMG.m_arrParameter[ve.i4].m_Para.y,rLMG.m_arrParameter[ve.i4].m_Para.w*0.5f);
						Vec3 v5=Vec3(rLMG.m_arrParameter[ve.i5].m_Para.x,rLMG.m_arrParameter[ve.i5].m_Para.y,rLMG.m_arrParameter[ve.i5].m_Para.w*0.5f);
						Vec3 v6=Vec3(rLMG.m_arrParameter[ve.i6].m_Para.x,rLMG.m_arrParameter[ve.i6].m_Para.y,rLMG.m_arrParameter[ve.i6].m_Para.w*0.5f);
						Vec3 v7=Vec3(rLMG.m_arrParameter[ve.i7].m_Para.x,rLMG.m_arrParameter[ve.i7].m_Para.y,rLMG.m_arrParameter[ve.i7].m_Para.w*0.5f);
						Vec3 ip = (v0*ve.w0 + v1*ve.w1 + v2*ve.w2 + v3*ve.w3 + v4*ve.w4 + v5*ve.w5 + v6*ve.w6 + v7*ve.w7) + Vec3(xmove2,0,0.05f);  
						g_pAuxGeom->DrawOBB(_obb1,ip,1,RGBA8(0x00,0x00,0x7f,0x00),eBBD_Extremes_Color_Encoded);
					}
					uint32 mem=rLMG.m_ParaGrid3D_2.get_alloc_size();
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"mem: %d",mem );	
					g_YLine+=21.0f;
				}

				//---------------------------------------------------------------------------------------------
				//---                   this is the 3D-parameterizer     --------------------------------------
				//---------------------------------------------------------------------------------------------
				if (1)
				{
					f32 cel0=f32(rLMG.m_cells0-1);
					f32 fx=(vDesiredParameter.x-rLMG.m_min0) / ((rLMG.m_max0-rLMG.m_min0)/cel0);
					fx=clamp(fx,0.0f,cel0-0.001f);
					int32 ix	=	int32(fx);
					f32 px		=	fx-f32(ix);

					f32 cel1=f32(rLMG.m_cells1-1);
					f32 fy=(vDesiredParameter.y-rLMG.m_min1) / ((rLMG.m_max1-rLMG.m_min1)/cel1);
					fy=clamp(fy,0.0f,cel1-0.001f);
					int32 iy	=	int32(fy);
					f32 py		=	fy-f32(iy);

					f32 cel3=f32(rLMG.m_cells3-1);
					f32 fw=(vDesiredParameter.w-rLMG.m_min3) / ((rLMG.m_max3-rLMG.m_min3)/cel3);
					fw=clamp(fw,0.0f,cel3-0.001f);
					int32 iw	=	int32(fw);
					f32 pw		=	fw-f32(iw);

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"fx: %f   fy: %f   fz: %f" , fx,fy,fz );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"dpx:%f dpy:%f dpz:%f     ix:%d iy:%d iz:%d    px:%f py:%f pz:%f",vDesiredParameter.x,vDesiredParameter.y,vDesiredParameter.z,   ix,iy,iz,  px,py,pz );	
					//	g_YLine+=21.0f;

					for (uint32 i=0; i<numExamples; i++) 
						arrWeights2[i]=0;

					uint32 idx;
					VExample3D ve;

					f32 ew0=(1.0f-pw)*(1-px)*(1-py);	
					idx =(iw+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+=f32(ve.w0)*ew0;	
					arrWeights2[ve.i1]+=f32(ve.w1)*ew0;	
					arrWeights2[ve.i2]+=f32(ve.w2)*ew0;	
					arrWeights2[ve.i3]+=f32(ve.w3)*ew0;	
					arrWeights2[ve.i4]+=f32(ve.w4)*ew0;	
					arrWeights2[ve.i5]+=f32(ve.w5)*ew0;	
					arrWeights2[ve.i6]+=f32(ve.w6)*ew0;	
					arrWeights2[ve.i7]+=f32(ve.w7)*ew0;	

					f32 ew1=(1.0f-pw)*px*(1-py);	
					idx=(iw+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+=f32(ve.w0)*ew1;
					arrWeights2[ve.i1]+=f32(ve.w1)*ew1;
					arrWeights2[ve.i2]+=f32(ve.w2)*ew1;
					arrWeights2[ve.i3]+=f32(ve.w3)*ew1;
					arrWeights2[ve.i4]+=f32(ve.w4)*ew1;
					arrWeights2[ve.i5]+=f32(ve.w5)*ew1;
					arrWeights2[ve.i6]+=f32(ve.w6)*ew1;
					arrWeights2[ve.i7]+=f32(ve.w7)*ew1;

					f32 ew2=(1.0f-pw)*(1-px)*py;	
					idx=(iw+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+= f32(ve.w0)*ew2;	
					arrWeights2[ve.i1]+= f32(ve.w1)*ew2;	
					arrWeights2[ve.i2]+= f32(ve.w2)*ew2;	
					arrWeights2[ve.i3]+= f32(ve.w3)*ew2;	
					arrWeights2[ve.i4]+= f32(ve.w4)*ew2;	
					arrWeights2[ve.i5]+= f32(ve.w5)*ew2;	
					arrWeights2[ve.i6]+= f32(ve.w6)*ew2;	
					arrWeights2[ve.i7]+= f32(ve.w7)*ew2;	

					f32 ew3=(1.0f-pw)*px*py;	
					idx=(iw+0)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0+(ix+1);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+= f32(ve.w0)*ew3;
					arrWeights2[ve.i1]+= f32(ve.w1)*ew3;
					arrWeights2[ve.i2]+= f32(ve.w2)*ew3;
					arrWeights2[ve.i3]+= f32(ve.w3)*ew3;
					arrWeights2[ve.i4]+= f32(ve.w4)*ew3;
					arrWeights2[ve.i5]+= f32(ve.w5)*ew3;
					arrWeights2[ve.i6]+= f32(ve.w6)*ew3;
					arrWeights2[ve.i7]+= f32(ve.w7)*ew3;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew2: %f idx2: %d  ew3: %f  idx3: %d",ew2,idx2, ew3,idx3 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"ew0: %f idx0: %d  ew1: %f  idx1: %d",ew0,idx0, ew1,idx1 );	
					//	g_YLine+=21.0f;

					//---------------------------------------------------------

					f32 ew4=pw*(1-px)*(1-py);	
					idx =(iw+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+=f32(ve.w0)*ew4;	
					arrWeights2[ve.i1]+=f32(ve.w1)*ew4;	
					arrWeights2[ve.i2]+=f32(ve.w2)*ew4;	
					arrWeights2[ve.i3]+=f32(ve.w3)*ew4;	
					arrWeights2[ve.i4]+=f32(ve.w4)*ew4;	
					arrWeights2[ve.i5]+=f32(ve.w5)*ew4;	
					arrWeights2[ve.i6]+=f32(ve.w6)*ew4;	
					arrWeights2[ve.i7]+=f32(ve.w7)*ew4;	

					f32 ew5=pw*px*(1-py);	
					idx=(iw+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+0)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+=f32(ve.w0)*ew5;
					arrWeights2[ve.i1]+=f32(ve.w1)*ew5;
					arrWeights2[ve.i2]+=f32(ve.w2)*ew5;
					arrWeights2[ve.i3]+=f32(ve.w3)*ew5;
					arrWeights2[ve.i4]+=f32(ve.w4)*ew5;
					arrWeights2[ve.i5]+=f32(ve.w5)*ew5;
					arrWeights2[ve.i6]+=f32(ve.w6)*ew5;
					arrWeights2[ve.i7]+=f32(ve.w7)*ew5;

					f32 ew6=pw*(1-px)*py;	
					idx=(iw+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+0);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+= f32(ve.w0)*ew6;	
					arrWeights2[ve.i1]+= f32(ve.w1)*ew6;	
					arrWeights2[ve.i2]+= f32(ve.w2)*ew6;	
					arrWeights2[ve.i3]+= f32(ve.w3)*ew6;	
					arrWeights2[ve.i4]+= f32(ve.w4)*ew6;	
					arrWeights2[ve.i5]+= f32(ve.w5)*ew6;	
					arrWeights2[ve.i6]+= f32(ve.w6)*ew6;	
					arrWeights2[ve.i7]+= f32(ve.w7)*ew6;	

					f32 ew7=pw*px*py;	
					idx=(iw+1)*rLMG.m_cells1*rLMG.m_cells0 + (iy+1)*rLMG.m_cells0 + (ix+1);
					ve = rLMG.m_ParaGrid3D_2[idx];
					arrWeights2[ve.i0]+= f32(ve.w0)*ew7;
					arrWeights2[ve.i1]+= f32(ve.w1)*ew7;
					arrWeights2[ve.i2]+= f32(ve.w2)*ew7;
					arrWeights2[ve.i3]+= f32(ve.w3)*ew7;
					arrWeights2[ve.i4]+= f32(ve.w4)*ew7;
					arrWeights2[ve.i5]+= f32(ve.w5)*ew7;
					arrWeights2[ve.i6]+= f32(ve.w6)*ew7;
					arrWeights2[ve.i7]+= f32(ve.w7)*ew7;

					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw6: %f idx6: %d  xw7: %f  idx7: %d", ew6,idx6, ew7,idx7 );	
					//	g_YLine+=21.0f;
					//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"xw4: %f idx4: %d  xw5: %f  idx5: %d", ew4,idx4, ew5,idx5 );	
					//	g_YLine+=21.0f;
				}
			}


			f32 sum1=0.0f;
			f32 sum2=0.0f;
			/*		for (uint32 i=0; i<numExamples; i++) 
			if (fabsf(arrWeights1[i])<0.0000000002f)		arrWeights1[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
			sum1+=arrWeights1[i];
			if (sum1==0)
			arrWeights1[0]=1.0f,sum1=1.0f;
			for (uint32 i=0; i<numExamples; i++)
			arrWeights1[i]/=sum1;	

			for (uint32 i=0; i<numExamples; i++) 
			if (fabsf(arrWeights2[i])<0.000000002f)		arrWeights2[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
			sum2+=arrWeights2[i];
			if (sum2==0)
			arrWeights2[0]=1.0f,sum2=1.0f;
			for (uint32 i=0; i<numExamples; i++)
			arrWeights2[i]/=sum2;	
			*/

			for (uint32 i=0; i<numExamples; i++)
				arrWeights[i]=(arrWeights1[i]+arrWeights2[i]);	


			f32 sum=0.0f;
			for (uint32 i=0; i<numExamples; i++) 
				if (fabsf(arrWeights[i])<0.02f)		arrWeights[i]=0;
			for (uint32 i=0; i<numExamples; i++) 
				sum+=arrWeights[i];
			if (sum==0)
				arrWeights[0]=1.0f,sum=1.0f;
			for (uint32 i=0; i<numExamples; i++)
				arrWeights[i]/=sum;	
			for (uint32 i=0; i<numExamples; i++)
				lmg.m_fBlendWeight[i]=arrWeights[i];	


		//	g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fCol1111, false,"sum1: %f  sum2: %f",sum1,sum2);	
		//	g_YLine+=21.0f;
		} //function PARA






		void ComputeWeight_PARA(SParametric & lmg, const CAnimationSet * pAnimationSet2, GlobalAnimationHeaderCAF* parrGlobalCAFs2, GlobalAnimationHeaderLMG& rLMG)
		{
			uint32 nDimensions	= rLMG.m_Dimensions;
			assert(nDimensions>0 && nDimensions<5);

			if (nDimensions==1)
				ComputeWeight_PARA1D(lmg,rLMG);
			if (nDimensions==2)
				ComputeWeight_PARA2D(lmg,rLMG);
			if (nDimensions==3)
				ComputeWeight_PARA3D(lmg,rLMG);
			if (nDimensions==4)
				ComputeWeight_PARA4D(lmg,rLMG);

			if (Console::GetInst().ca_DrawVEGInfo ) 
			{
				f32 xmove1=3;
				f32 xmove2=-(rLMG.m_max0+3);

				uint32 numExamples	= rLMG.m_arrBSAnimations.size();
				uint32 numParameter	=	rLMG.m_arrParameter.size(); 
				static Ang3 angles=Ang3(0,0,0);
				angles+=Ang3(0.01f,0.02f,0.03f);
				AABB aabb = AABB(Vec3( -0.05f, -0.05f, -0.05f),Vec3( 0.05f, 0.05f, 0.05f));

				ColorB col[256];
				for (uint32 p=0; p<numParameter; p++)
				{
					if (p<numExamples)
						col[p]=RGBA8(0x00,0x3f,0x00,0x00);
					else
						col[p]=RGBA8(0x3f,0x00,0x00,0x00);
				}

				Matrix33 _m33=Matrix33::CreateRotationXYZ(angles);
				OBB _obb=OBB::CreateOBBfromAABB( _m33,aabb );

				for (uint32 p=0; p<numParameter; p++)
				{
					f32 x=rLMG.m_arrParameter[p].m_Para.x;
					f32 y=rLMG.m_arrParameter[p].m_Para.y;
					f32 z=rLMG.m_arrParameter[p].m_Para.z;
					if (p<numExamples)
					{
						col[p]=RGBA8(0x00,0xff,0x00,0x00);
						g_pAuxGeom->DrawOBB(_obb,Vec3(xmove1+x,y,z),1,col[p],eBBD_Extremes_Color_Encoded);
						g_pIRenderer->DrawLabel(Vec3(xmove1+x,y,z), 1.5f, "%d", p);
					}
					else
					{
						col[p]=RGBA8(0xff,0x00,0x00,0x00);
						g_pAuxGeom->DrawOBB(_obb,Vec3(xmove1+x,y,z),1,col[p],eBBD_Extremes_Color_Encoded);
						g_pIRenderer->DrawLabel(Vec3(xmove1+x,y,z), 1.5f, "%d", p);
					}
					/*
					if (p<numExamples)
					{
					float fColDebug[4];
					fColDebug[0]=col[p].r/256.0f;
					fColDebug[1]=col[p].g/256.0f;
					fColDebug[2]=col[p].b/256.0f;
					fColDebug[3]=1;
					g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"ParaX: %f ParaY: %f ParaZ: %f   fWeight: %f",x,y,z,lmg.m_fBlendWeight[p] );	
					g_YLine+=16.0f;
					}*/
				}

				if (nDimensions==4)
				{
					for (uint32 p=0; p<numParameter; p++)
					{
						f32 x=rLMG.m_arrParameter[p].m_Para.x;
						f32 y=rLMG.m_arrParameter[p].m_Para.y;
						f32 w=rLMG.m_arrParameter[p].m_Para.w;
						if (p<numExamples)
						{
							col[p]=RGBA8(0x00,0xff,0x00,0x00);
							g_pAuxGeom->DrawOBB(_obb,Vec3(xmove2+x,y,w),1,col[p],eBBD_Extremes_Color_Encoded);
							g_pIRenderer->DrawLabel(Vec3(xmove2+x,y,w), 1.5f, "%d", p);
						}
						else
						{
							col[p]=RGBA8(0xff,0x00,0x00,0x00);
							g_pAuxGeom->DrawOBB(_obb,Vec3(xmove2+x,y,w),1,col[p],eBBD_Extremes_Color_Encoded);
							g_pIRenderer->DrawLabel(Vec3(xmove2+x,y,w), 1.5f, "%d", p);
						}
						/*
						if (p<numExamples)
						{
						float fColDebug[4];
						fColDebug[0]=col[p].r/256.0f;
						fColDebug[1]=col[p].g/256.0f;
						fColDebug[2]=col[p].b/256.0f;
						fColDebug[3]=1;
						g_pIRenderer->Draw2dLabel( 1,g_YLine, 1.6f, fColDebug, false,"ParaX: %f ParaY: %f ParaZ: %f   fWeight: %f",x,y,z,lmg.m_fBlendWeight[p] );	
						g_YLine+=16.0f;
						}*/
					}
				}


			}
		}
	} 
} // namespace LMG









namespace LMG
{
	void CheckBlendWeights(const CAnimationSet* pAnimationSet, SParametric& lmg)
	{
		if (lmg.m_nParametricID>=0)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			f32 fTotal=0.0f;
			uint32 numAssets = rGlobalAnimHeader.m_arrBSAnimations.size();
			for (uint32 i=0; i<numAssets; i++)
				fTotal += lmg.m_fBlendWeight[i];
			assert( fabsf(fTotal-1.0f)<0.005f );
			if (fTotal==0)
				lmg.m_fBlendWeight[0]=1.0f;


			uint32 nExtrapolation1=0;
			for (uint32 i=0; i<numAssets; i++)
				nExtrapolation1 |= uint32(lmg.m_fBlendWeight[i]<-5.2f);

			uint32 nExtrapolation2=0;
			for (uint32 i=0; i<numAssets; i++)
				nExtrapolation2 |= uint32(lmg.m_fBlendWeight[i]>5.2f);

			if( fabsf(fTotal-1.0f)>0.005f || nExtrapolation1 || nExtrapolation2 )
			{
				assert(!"Sum of weights is wrong");
				char blendCode[5];
				blendCode[0] = (rGlobalAnimHeader.m_nBlendCodeLMG >>  0) & 0xff;
				blendCode[1] = (rGlobalAnimHeader.m_nBlendCodeLMG >>  8) & 0xff;
				blendCode[2] = (rGlobalAnimHeader.m_nBlendCodeLMG >> 16) & 0xff;
				blendCode[3] = (rGlobalAnimHeader.m_nBlendCodeLMG >> 24) & 0xff;
				blendCode[4] = 0;
				CryWarning(VALIDATOR_MODULE_ANIMATION, VALIDATOR_ERROR, "Sum of weights is wrong. LMG blend code is \'%s\'", blendCode);
			}
		}
	}

	void ComputeWeight(const CAnimationSet* pAnimationSet, SParametric& lmg)
	{
		for (uint32 i=0; i<MAX_LMG_ANIMS; i++)
			lmg.m_fBlendWeight[i]=0;

		if (lmg.m_nParametricID>=0)
		{
			const ModelAnimationHeader* pAnim = pAnimationSet->GetModelAnimationHeader(lmg.m_nParametricID);
			assert(pAnim->m_nAssetType==LMG_File);
			GlobalAnimationHeaderLMG& rLMG = g_AnimationManager.m_arrGlobalLMG[pAnim->m_nGlobalAnimId];

			assert(rLMG.m_nBlendCodeLMG);

			GlobalAnimationHeaderCAF* parrGlobalAnimations = &g_AnimationManager.m_arrGlobalCAF[0];		

			uint32 nBlendCode = rLMG.m_nBlendCodeLMG;

			switch( AnimCodeLookup::ComputeAnimCode(nBlendCode) )
			{
#define DRY(X) case AnimCodeLookup::X: \
	_private::ComputeWeight_##X( lmg, pAnimationSet, parrGlobalAnimations, rLMG ); break;
#include "LMG_Types.inc"
#undef DRY
			}
		}
		else
		{
			lmg.m_fBlendWeight[0]=1;
		}
	}


	/*
	TW GetTimewarpedDuration(CAnimationSet* pAnimationSet, const SParametric& lmg, f32 fDeltaTime)
	{
	TW tw;
	PrefetchLine(lmg.m_fBlendWeight, 0);
	if (lmg.m_nAnimID[0]<0)
	return tw;
	PrefetchLine(lmg.m_fBlendWeight, 128);
	const int32 kNumAnims = lmg.m_numAnims;
	for (int32 i=0; i<kNumAnims; i++)
	{
	int32 nAnimID = lmg.m_nAnimID[i];
	const ModelAnimationHeader* pAnim = SPU_MAIN_PTR( pAnimationSet->GetModelAnimationHeader(nAnimID) );

	if (pAnim->m_nAssetType==CAF_File)
	{
	GlobalAnimationHeaderCAF& rGAH = g_AnimationManager.m_arrGlobalCAF[pAnim->m_nGlobalAnimId];
	int32 segcount = lmg.m_nSegmentCounter[i];
	f32 fSegTime = rGAH.GetSegmentDuration(segcount);

	f32 fTotTime = rGAH.m_fTotalDuration;
	if (fTotTime==0)
	fTotTime=SECONDS_PER_TICK;

	if (fSegTime != fTotTime)
	{
	f32 d0 = rGAH.GetSegmentDuration(segcount);
	if (d0==0)
	d0=SECONDS_PER_TICK;
	tw.m_fDeltaTime		+= lmg.m_fBlendWeight[i]*(fDeltaTime/d0);
	tw.m_fDuration	  += d0*lmg.m_fBlendWeight[i];
	}
	else
	{
	tw.m_fDeltaTime		+= lmg.m_fBlendWeight[i]*(fDeltaTime/fTotTime);
	tw.m_fDuration		+= lmg.m_fBlendWeight[i]*fTotTime;
	}
	}
	if (pAnim->m_nAssetType==AIM_File)
	{
	GlobalAnimationHeaderAIM& rGAH = g_AnimationManager.m_arrGlobalAIM[pAnim->m_nGlobalAnimId];
	f32 fTotTime = rGAH.m_fTotalDuration;
	if (fTotTime==0)
	fTotTime=SECONDS_PER_TICK;
	tw.m_fDuration  += lmg.m_fBlendWeight[i]*fTotTime;
	}
	}
	// 	assert(fDuration);
	return tw;
	}*/



	TW GetTimewarpedDuration(const CAnimationSet* pAnimationSet, const SParametric& lmg, f32 fDeltaTime)
	{
		TW tw;

		PrefetchLine(lmg.m_fBlendWeight, 0);

		if (lmg.m_nAnimID[0] >= 0)
		{
			PrefetchLine(lmg.m_fBlendWeight, 128);

			const int32 kNumAnims = lmg.m_numAnims;
			for (int32 i=0; i<kNumAnims; i++)
			{
				int32 nAnimID = lmg.m_nAnimID[i];
				const ModelAnimationHeader* pAnim = SPU_MAIN_PTR( pAnimationSet->GetModelAnimationHeader(nAnimID) );

				if (pAnim->m_nAssetType==CAF_File)
				{
					GlobalAnimationHeaderCAF& rGAH = g_AnimationManager.m_arrGlobalCAF[pAnim->m_nGlobalAnimId];
					int32 segcount = lmg.m_nSegmentCounter[i];
					f32 fSegTime = rGAH.GetSegmentDuration(segcount);
					fSegTime = max(fSegTime, SECONDS_PER_TICK);

					tw.m_fDeltaTime		+= lmg.m_fBlendWeight[i]*(fDeltaTime/fSegTime);
					tw.m_fDuration	  += fSegTime*lmg.m_fBlendWeight[i];
				}
				else if (pAnim->m_nAssetType==AIM_File)
				{
					GlobalAnimationHeaderAIM& rGAH = g_AnimationManager.m_arrGlobalAIM[pAnim->m_nGlobalAnimId];
					f32 fTotTime = rGAH.m_fTotalDuration;
					if (fTotTime==0)
						fTotTime=SECONDS_PER_TICK;

					tw.m_fDuration  += lmg.m_fBlendWeight[i]*fTotTime;
				}


			}
		}

		// 	assert(fDuration);
		return tw;
	}

} // namespace LMG